Longest String Chain
第6天。
今天的题目是Longest String Chain:
Given a list of words, each word consists of English lowercase letters.
Let’s say word1
is a predecessor of word2
if and only if we can add exactly one letter anywhere in word1
to make it equal to word2
. For example, "abc"
is a predecessor of "abac"
.
A word chain is a sequence of words [word_1, word_2, ..., word_k]
with k >= 1
, where word_1
is a predecessor of word_2
, word_2
is a predecessor of word_3
, and so on.
Return the longest possible length of a word chain with words chosen from the given list of words
.
Example 1:
1 | Input: ["a","b","ba","bca","bda","bdca"] |
Note:
1 <= words.length <= 1000
1 <= words[i].length <= 16
words[i]
only consists of English lowercase letters.
看到这道题的时候,一开始以为要先转化成图来做,但是感觉好像有点复杂化这个问题了,尝试手动跑了一下样例,发现存在最优子结构,因此我们可以用动态规划来做。动规方程如下:
$$
dp[i] = max({dp[j] + 1 | isPredecessor(words[i], words[j]) == true });
$$
简单解释一下这个方程(可能写的不是很规范),$dp[i]$ 表示以第i 个字符串为结尾的最长String Chain
的长度。我们可以用第 i 个字符串的所有Predecessor
的 dp 值最大值再加一得到。
同时,为了加速,我们可以先对原始的字符串序列做一次按长度的排序。这样就很容易找到和当前字符串长度相差1的字符串了,这样我们在找所有Predecessor
的时候不需要遍历所有数组。
有了动规方程,我们写出这个代码就简单多了,只要按着类似的套路即可。
这样我们代码就只剩下如何判读一个字符串是否是另一个字符串的Predecessor
,其实这个问题也挺简单的,只要两个循环即可。
1 | bool isPredecessor(string &s1, string &s2) { |