1048. Longest String Chain

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 ( n 2 ∗ l ) O(n^2*l) O(n2l)。n是words数组长度,l是每个单词的长度。

猜你喜欢

转载自blog.csdn.net/flying_all/article/details/112108940
今日推荐