给出一个单词列表,其中每个单词都由小写英文字母组成。
如果我们可以在 word1
的任何地方添加一个字母使其变成 word2
,那么我们认为 word1
是 word2
的前身。例如,"abc"
是 "abac"
的前身。
词链是单词 [word_1, word_2, ..., word_k]
组成的序列,k >= 1
,其中 word_1
是 word_2
的前身,word_2
是 word_3
的前身,依此类推。
从给定单词列表 words
中选择单词组成词链,返回词链的最长可能长度。
示例:
输入:["a","b","ba","bca","bda","bdca"] 输出:4 解释:最长单词链之一为 "a","ba","bda","bdca"。
提示:
1 <= words.length <= 1000
1 <= words[i].length <= 16
words[i]
仅由小写英文字母组成。
思路:
先把words按元素长度排好序,然后线性扫描words,
对于words里的每个元素word, 往后找长度比它大一的元素word[j],
然后比较一下word[j] 是不是能从word里加一个字母得到。
class Solution(object):
def longestStrChain(self, words):
"""
:type words: List[str]
:rtype: int
"""
from collections import Counter
words = sorted(words, key = lambda x: len(x))
def cover(str1, str2):
tmp = ""
for i, char in enumerate(str2):
tmp = str2[:i] + str2[i + 1:]
if tmp == str1:
return True
return False
dp = [1 for _ in range(len(words))]
for i, word in enumerate(words):
if i >= 1 and words[i] == words[i - 1]: #去重
continue
for j in range(i + 1, len(words)):
if len(words[j]) == len(word): #长度相等不考虑
continue
if len(words[j]) - 1 > len(word): #长度差超过1也不考虑
break
if len(words[j]) - 1 == len(word) and cover(word, words[j]):
dp[j] = max(dp[j], dp[i] + 1)
return max(dp)