文章目录
- 1题目理解
- 2 动态规划
1题目理解
输入:字符串数组words,字符串只包含小写字母
规则:对于word1和word2,如果在word1中任何一个位置添加一个字符能够得到word2,那么可以称word1为word2的前身。词链是单词 [word_1, word_2, …, word_k] 组成的序列,k >= 1,其中 word_1 是 word_2 的前身,word_2 是 word_3 的前身,依此类推。
输出:从words中选择词组成词链,词链可能的最长的长度。
Example 1:
Input: words = [“a”,“b”,“ba”,“bca”,“bda”,“bdca”]
Output: 4
Explanation: One of the longest word chain is “a”,“ba”,“bda”,“bdca”.
Example 2:
Input: words = [“xbc”,“pcxbcf”,“xb”,“cxbc”,“pcxbc”]
Output: 5
看了例子2,怎么也不明白怎么会是5,我觉得应该是3才对。这道题目和Longest Increasing Subsequence 是类似的。看了别人的答案才知道,从words中选择词,并没有说一定要按照顺序组成词链。选择n个词,之后可以按任意顺序组成词链,与原数组的下标无关。
2 动态规划
解题思路也和Longest Increasing Subsequence 是一样的。
class Solution {public int longestStrChain(String[] words) {int n = words.length;Arrays.sort(words, Comparator.comparingInt(String::length));int[] dp = new int[n];dp[0] = 1;int max = 1;for(int i=1;i<n;i++){dp[i] = 1;for(int j=0;j<i;j++){if(isPredecessor(words[j],words[i])){dp[i] = Math.max(dp[i],dp[j]+1);}}max = Math.max(max,dp[i]);}return max;}private boolean isPredecessor(String word1,String word2){if(word1.length()+1==word2.length()){int dis = 0;for(int i=0,j=0;i<word1.length() && j<word2.length();){if(word1.charAt(i) == word2.charAt(j)){j++;i++;}else{j++;dis++;}}return dis<=1;}return false;}
}
时间复杂度O(n2∗l)O(n^2*l)O(n2∗l)。n是words数组长度,l是每个单词的长度。