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 <= words.length <= 1000
- 1 <= words[i].length <= 16
- 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;
}
};