Longest String Chain

原题链接

在这里插入图片描述
一般来说这种求最长序列问题都可以用动态规划来解决,那么这道题也不例外。核心的思路是将用一长度的字符串都压到同一个栈中,然后从最长的字符串开始往最短的逐级计算最长序列。还有一个地方关键点是判断两个字符串是否是有效的,即字符串w1和w2是否为长度差1,并且往w1中任意位置插入一个字符就可以得到w2.关键是找到状态转换方程,在这道题里面,我们用map<string,int> maxlen来记录以该字符串开头的序列的最长长度,状态转换方程为:

maxlen[w1]=max(maxlen[w1],maxlen[w2]+1);

class Solution {
public:
   bool isvalid(const string &a,const string &b){
       int idxa = 0,idxb = 0;
       int alen =a.size(),blen=b.size();
       int count =0;
       while(idxa<alen&&idxb<blen){
           if(a[idxa]!=b[idxb]){
               count++;
               idxb++;
           }
           else{
               idxa++;
               idxb++;
           }
           if(count>1)return false;
       }
       return true;
       
   }
    int longestStrChain(vector<string>& words) {
        int res = 1;
         map<int,vector<string>> mp;
        for(int i=1;i<=16;i++)
            mp[i]={};
        
        map<string,int>maxlen;
        for(auto w:words)
            mp[w.size()].push_back(w);
        
        int idx =16;
        while(mp[idx].size()==0)idx--;
        auto first = mp[idx];
        int len1 =idx,len2=0;
       
    
        vector<string>  second;
        for(auto w:first){
           
            maxlen[w]=1;
        }
    
        while(idx){
           idx--;
           
           second = mp[idx];
            if(second.size()==0){
                first=second;
                len1 = len2;
                continue;
            }
            len2=idx;
            
            for(auto w:second){
                maxlen[w]=1;
              
            }
         
            if(len2==len1-1){
               for(auto w1:second){
                  for(auto w2:first)
                      if(isvalid(w1,w2)){
                       
                          maxlen[w1]=max(maxlen[w1],maxlen[w2]+1);
                      }
                   res = max(res,maxlen[w1]);
    
               }
            }
            first = second;
            len1 = len2;
        }
        return res;
        
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值