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;
        
    }
};
这段代码是一个区块链的实现中的获取最长链的函数,其主要思路是遍历所有区块,从每个区块出发,向前查找每个区块的前一个区块是否在当前区块链中存在,并且不是根节点'root'。如果找到了前一个区块,则将其加入到当前链表的头部。最终,如果当前链表的长度大于已经找到的最长链长度,则将当前链表作为最长链。 这个函数可能需要一些解释,下面是对代码每行的解释: 1. `longestChain () {`: 定义一个函数叫做`longestChain`。 2. `let longestChain = [];`: 初始化一个最长链为空数组。 3. `for (const [hash, block] of this.blocks) {`: 遍历所有区块,使用解构赋值获取当前区块的哈希值和区块本身。 4. `const chain = [block];`: 初始化一个当前链表,将当前区块加入其中。 5. `let previousBlock = block;`: 初始化一个前一个区块,将其赋值为当前区块。 6. `while (this.blocks.has(previousBlock.previousHash) && (this.blocks.has(previousBlock.previousHash)).has !== 'root') {`: 在当前区块链中查找前一个区块,如果找到且前一个区块不是根节点'root',则进入循环。 7. `previousBlock = this.blocks.get(previousBlock.previousHash);`: 将前一个区块作为当前区块,继续向前查找。 8. `chain.unshift(previousBlock);`: 将前一个区块加入到当前链表的头部。 9. `if (chain.length > longestChain.length) {`: 判断当前链表是否比已经找到的最长链更长。 10. `longestChain = chain;`: 如果当前链表更长,则将其作为最长链。 11. `console.log(longestChain)`: 输出最长链到控制台。 12. `return longestChain;`: 返回最长链。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值