1048 最长字符串链

题目描述:
给出一个单词列表,其中每个单词都由小写英文字母组成。
如果我们可以在 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] 仅由小写英文字母组成。

方法1:
主要思路:解题汇总链接
(1)动态规划;
(2)先将原数组使用字符串的长度进行排序;
(3)然后遍历排序后的数组,将字符串放入动态存储数据结构unordered_map来存储使用当前字符串作为链的结尾字符串,能够获得最长的链的长度;
(4)对于每个当前的字符串,找出各个长度减1的子字符串,然后判断该字符串是否存在于dp中,若存在,则更新可能的长度;

class Solution {
public:
    int longestStrChain(vector<string>& words) {
        sort(words.begin(),words.end(),[](string&lhs,string&rhs){//根据字符串的长度进行排序
            return lhs.size()<rhs.size();
        });
        unordered_map<string,int> dp;//存储以各个字符串作为链的尾部字符串的最长长度
        int max_len=1;
        for(string&word:words){//遍历各个字符串
            dp[word]=1;//初始化
            int len=word.size()-1;//前一个字符串的长度
            if(len==0){
                continue;
            }
            //获得各个可能的组成的子字符串
            for(int i=0;i<=len;++i){
                string sub=word.substr(0,i);
                sub+=word.substr(i+1,len-i);
                if(dp.count(sub)){//若存在子字符串,则更新
                    dp[word]=max(dp[word],dp[sub]+1);
                }
            }
            max_len=max(max_len,dp[word]);//更新最长的长度
        }
        return max_len;
    }
};

你可能感兴趣的:(LeetCode)