1048. Longest String Chain


Given a list of words, each word consists of English lowercase letters.

Let’s say word1 is a predecessor of word2 if and only if we can add exactly one letter anywhere in word1 to make it equal to word2. For example, “abc” is a predecessor of “abac”.

A word chain is a sequence of words [word_1, word_2, …, word_k] with k >= 1, where word_1 is a predecessor of word_2, word_2 is a predecessor of word_3, and so on.

Return the longest possible length of a word chain with words chosen from the given list of words.

Example 1:

Input: [“a”,“b”,“ba”,“bca”,“bda”,“bdca”]
Output: 4
Explanation: one of the longest word chain is “a”,“ba”,“bda”,“bdca”.

Note:

  1. 1 <= words.length <= 1000
  2. 1 <= words[i].length <= 16
  3. words[i] only consists of English lowercase letters.

方法1: dynamic programming

思路:

LIS。

Complexity

Time complexity: O(n^2)
Space complexity: O(n)

class Solution {
public:
    int longestStrChain(vector<string>& words) {
        if (words.empty()) return 0;
        int n = words.size(), result = 1;
        auto cmp = [](string & a, string& b) {
            return a.size() < b.size();
        };
        sort(words.begin(), words.end(), cmp);
        vector<int> dp(n, 1);
        
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (isPre(words[j], words[i])) {
                    dp[i] = max(dp[i], dp[j] + 1);
                }
                result = max(result, dp[i]);
            }
        }
        return result;
    }
    
    bool isPre(string & a, string & b) {
        if (a.size() >= b.size()) return false;
        for (int i = 0; i < b.size(); i++) {
            if (a[i] != b[i]) return a.substr(i) == b.substr(i + 1);
        }
        return true;
    }
};

方法2: hash + dp

思路:

Complexity

Time complexity: O(n)
Space complexity: O(n)

class Solution {
public:
    int longestStrChain(vector<string>& words) {
        if (words.empty()) return 0;
        int n = words.size(), result = 1;
        auto cmp = [](string & a, string& b) {
            return a.size() < b.size();
        };
        sort(words.begin(), words.end(), cmp);
        vector<int> dp(n, 1);
        unordered_map<string, int> hash;
        
        for (int i = 0; i < n; i++) {
            hash[words[i]] = i;
            int idx = hasPre(words[i], hash);
            if (idx != -1) {
                dp[i] = max(dp[i], dp[idx] + 1);
            }
            result = max(result, dp[i]);
        }
        return result;
    }
    
    int hasPre(string & b, unordered_map<string, int> & hash) {
        for (int i = 0; i < b.size(); i++) {
            string a = b.substr(0, i) + b.substr(i + 1);
            if (hash.count(a)) return hash[a];
        }
        return -1;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码是一个区块链的实现中的获取最长链的函数,其主要思路是遍历所有区块,从每个区块出发,向前查找每个区块的前一个区块是否在当前区块链中存在,并且不是根节点'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、付费专栏及课程。

余额充值