给出一个单词数组 words ,其中每个单词都由小写英文字母组成。
如果我们可以 不改变其他字符的顺序 ,在 wordA 的任何地方添加 恰好一个 字母使其变成 wordB ,那么我们认为 wordA 是 wordB 的 前身 。
例如,"abc" 是 "abac" 的 前身 ,而 "cba" 不是 "bcad" 的 前身
词链是单词 [word_1, word_2, ..., word_k] 组成的序列,k >= 1,其中 word1 是 word2 的前身,word2 是 word3 的前身,依此类推。一个单词通常是 k == 1 的 单词链 。
从给定单词列表 words 中选择单词组成词链,返回 词链的 最长可能长度 。
示例 1:
输入:words = ["a","b","ba","bca","bda","bdca"]
输出:4
解释:最长单词链之一为 ["a","ba","bda","bdca"]
示例 2:
输入:words = ["xbc","pcxbcf","xb","cxbc","pcxbc"]
输出:5
解释:所有的单词都可以放入单词链 ["xb", "xbc", "cxbc", "pcxbc", "pcxbcf"].
示例 3:
输入:words = ["abcd","dbqca"]
输出:1
解释:字链["abcd"]是最长的字链之一。
["abcd","dbqca"]不是一个有效的单词链,因为字母的顺序被改变了。
提示:
1 <= words.length <= 1000
1 <= words[i].length <= 16
words[i] 仅由小写英文字母组成。
#解题思想:
看了lc上面的题解,感觉这个人说的最简单易懂:
全局链条最大长度肯定是随着枚举的字符长度单调递增的。
所以先按照字符长短排序,可以减少重复比较。
用一个字典保存每个字符结尾链条的最大长度,思想类似于最长递增子序列,而本题只是组成链条的条件变了,差一个字母即可配对,所以枚举当前串w所有的-1子字符串curr_w,和字典里的链条尾部匹配,取最长的结果,作为w的最大长度,以此类推,见过的最大长度即为答案。
#解题代码:
class Solution(object):
def longestStrChain(self, words):
"""
:type words: List[str]
:rtype: int
"""
# sort the words, reversely, store them in the dic
# for loop the cur_word, find the child of this word see if it is in the dic
# if it is in the dictionary, we can keep looping and calling the function, to find the next one
# bdca: 1 bca: 1 + d[bdca] ba: 1 + d[bca] a: 1 + d[ba] -- recursion logic
words.sort(key = len, reverse = True)
d = collections.defaultdict(int)
# print(words)
for word in words:
d[word] = 1
for word in words:
for i in range(len(word)):
cur_word = word[:i] + word[i+1:]
if cur_word in d:
d[cur_word] = max(d[cur_word] ,1 + d[word])
# print(d)
return max(d.values())
# time: nlogn + n * l * l (l means the len of the word)
# space: n - number of data to store the word and the count
#时空复杂度:
时间复杂度:NlogN + N * L * L - 排序 + 第一个for循环+ word单词的长度 + word的child词长度
空间复杂度:O(N), 字典和排序需要的开销。
#解题思路:
我觉得有些题如果看了看题目感觉能自己一下子就做出来,秒杀的话,就不要浪费时间总结了。明天还是把时间和精力放在那些,第一眼看不出来,没有真正想明白,需要花时间去一步一步弄清楚的题目上面。先难后易!先难后易!加油!