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']
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
时间复杂度:O(n^2)
空间复杂度:O(n)
请注意,这也可以确保单词的顺序是完整的。你知道吗
在实际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)
一个可能的解决方案,在O(n)时间内运行:
我们追踪最后一封信中最长的链子。如果每个新词的第一个字母不是任何链的末端,则可以开始一个新链,或者添加到已找到的以该字母结尾的最长链中。你知道吗
反过来,这个新的链子可能是以当前单词的最后一个字母结尾的最长的链子,或者我们可以丢弃它。你知道吗
最后,我们只需要保留最长的链条。你知道吗
请注意,我将您的原始列表重命名为
words
,因为命名它list
会掩盖相同名称的Python内置。你知道吗我洗澡的时候在想这个问题,我想出了一个解决办法。回到这个问题,我发现Thierry Lathuille's answer已经包含了相同的基本算法。但我认为我的实现稍微优化了一点,也稍微有点像python:
这个实现实际上返回最长的链,尽管您可以很容易地将其简化为只跟踪长度(如果您需要的话)。你知道吗
恭喜你成功的nerd-sniped我!你知道吗
know
开始,我们知道know
前面什么都没有。所以,我们把它的值设为1
。你知道吗took
。took
有know
来建立您所描述的连接。所以,现在对于took
,值是2
(因为链中有两个单词)。你知道吗[4,4,1,3,1,2,1]
。你知道吗伪代码(因为我不是python爱好者):
在实际Python中:
相关问题 更多 >
编程相关推荐