Skip to content

Latest commit

 

History

History
 
 

1048. Longest String Chain

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

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.

 

Related Topics:
Hash Table, Dynamic Programming

Solution 1. Top-down DP

// OJ: https://leetcode.com/problems/longest-string-chain/
// Author: github.com/lzl124631x
// Time: O(N * S^2)
// Space: O(NS)
class Solution {
    unordered_map<string, int> m; 
    int dp(const string &s) {
        if (m[s]) return m[s];
        if (s.size() == 1) return 1;
        int ans = 1;
        for (int i = 0; i < s.size(); ++i) {
            auto copy = s;
            copy.erase(begin(copy) + i);
            if (m.count(copy)) {
                ans = max(ans, 1 + dp(copy));
            }
        }
        return m[s] = ans;
    }
public:
    int longestStrChain(vector<string>& A) {
        for (auto &s : A) m[s] = 0;
        int ans = 0;
        for (const auto &[s, len] : m) {
            ans = max(ans, dp(s));
        }
        return ans;
    }
};

Solution 2. Bottom-up DP

// OJ: https://leetcode.com/problems/longest-string-chain/
// Author: github.com/lzl124631x
// Time: O(N * S^2)
// Space: O(NS)
class Solution {
public:
    int longestStrChain(vector<string>& A) {
        sort(begin(A), end(A), [](auto &a, auto &b) { return a.size() < b.size(); });
        unordered_map<string, int> dp;
        int ans = 1;
        for (auto &s : A) {
            dp[s] = 1;
            for (int i = 0; i < s.size(); ++i) {
                auto next = s.substr(0, i) + s.substr(i + 1);
                if (dp.count(next)) {
                    dp[s] = max(dp[s], dp[next] + 1);
                    ans = max(ans, dp[s]);
                }
            }
        }
        return ans;
    }
};