我有一个类似的列表
list=["apple","white","loop","edit","tow","took","know"]
我想打印最长的字符串(接下来的单词以上一个字母开头),而无需更改单词的顺序,例如:
4
(苹果,修改,拍摄,知道) 而且我不能(苹果,修改,拍摄,知道,白色),因为我需要更改订单
答案 0 :(得分:2)
可行的解决方案,运行时间为O(n):
我们会追踪遇到的每个字母中最长的链条。如果每个新单词的第一个字母不是任何一个链的末尾,则可以开始一个新的链,也可以将其添加到以该字母结尾的最长链中。
反过来,这条新链可能是最长的,以当前单词的最后一个字母结尾的链,或者我们可以丢弃它。
最后,我们只需要保留所有找到的链中最长的一个即可。
words = ["apple","white","loop","edit","tow","took","know"]
found_ends = {}
for word in words:
if word[0] in found_ends:
# This word can make a chain longer
new_chain = found_ends[word[0]] + [word]
else:
# We start a new one
new_chain = [word]
# Is it the new longest chain for an end letter?
if word[-1] not in found_ends or len(found_ends[word[-1]]) < len(new_chain):
found_ends[word[-1]] = new_chain
print(max(found_ends.values(), key=len))
# ['apple', 'edit', 'took', 'know']
请注意,我将您的原始列表重命名为words
,因为将其命名为list
掩盖了同名的Python内置函数。
答案 1 :(得分:1)
list = ["apple","white","loop","edit","tow","took","know"] , answer = 4
know
开始,我们知道know
前面没什么。因此,我们将其值设置为1
。took
。如上所述,took
有know
建立连接。因此,现在对于took
,该值为2
(因为链中有2个单词)。[4,4,1,3,1,2,1]
。 伪代码(因为我不是Python爱好者):
chain_lengths = new int[words.length]
max_length = 0
for i = words.length - 1 to 0
chain_lengths[i] = 1
for j = i + 1 to words.length
if last_char(words[i]) == first_char(words[j]):
chain_lengths[i] = max(chain_lengths[i],chain_lengths[j] + 1)
max_length = max(chain_lengths[i],max_length)
print max_length
在实际的Python中:
words = ["apple","white","loop","edit","tow","took","know"]
chain_lengths = [None]*len(words)
max_length = 0
for i in range(len(words)-1,-1,-1):
chain_lengths[i] = 1
for j in range(i+1, len(words)):
if words[i][-1] == words[j][0]:
chain_lengths[i] = max(chain_lengths[i],chain_lengths[j] + 1)
max_length = max(chain_lengths[i],max_length)
答案 2 :(得分:0)
洗澡时我在想这个问题,想出了一个解决方案。我回到这个问题,发现Thierry Lathuille's answer已经包含相同的基本算法。但是我认为我的实现稍微更优化了,Pythonic也更简单了:
def longest_chain(words):
chains = defaultdict(list)
longest = []
for word in reversed(words):
first_char = word[0]
last_char = word[-1]
chain = chains[last_char] + [word]
if len(chain) > len(chains[first_char]):
chains[first_char] = chain
if len(chain) > len(longest):
longest = chain
return list(reversed(longest))
此实现实际上返回最长的链,尽管您可以轻松地简化它以仅跟踪长度(如果需要的话)。
恭喜您成功nerd-sniped我!