最大的字符串,可能的是

时间:2018-11-11 13:11:00

标签: python algorithm

我有一个类似的列表

list=["apple","white","loop","edit","tow","took","know"]

我想打印最长的字符串(接下来的单词以上一个字母开头),而无需更改单词的顺序,例如:

4

(苹果,修改,拍摄,知道) 而且我不能(苹果,修改,拍摄,知道,白色),因为我需要更改订单

3 个答案:

答案 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。如上所述,tookknow建立连接。因此,现在对于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
  • 时间复杂度: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)

答案 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我!