Longest String Chain - Very Easy Hashmap solution + Analysis
Problem Statement:
You are given an array of words
where each word consists of lowercase English letters.
wordA
is a predecessor of wordB
if and only if we can insert exactly one letter anywhere in wordA
without changing the order of the other characters to make it equal to wordB
.
- For example,
"abc"
is a predecessor of"abac"
, while"cba"
is not a predecessor of"bcad"
.
A word chain is a sequence of words [word1, word2, ..., wordk]
with k >= 1
, where word1
is a predecessor of word2
, word2
is a predecessor of word3
, and so on. A single word is trivially a word chain with k == 1
.
Return the length of the longest possible word chain with words chosen from the given list of words
.
Example 1:
Input: words = ["a","b","ba","bca","bda","bdca"] Output: 4 Explanation: One of the longest word chains is ["a","ba","bda","bdca"].
Example 2:
Input: words = ["xbc","pcxbcf","xb","cxbc","pcxbc"] Output: 5 Explanation: All the words can be put in a word chain ["xb", "xbc", "cxbc", "pcxbc", "pcxbcf"].
Example 3:
Input: words = ["abcd","dbqca"] Output: 1 Explanation: The trivial word chain ["abcd"] is one of the longest word chains. ["abcd","dbqca"] is not a valid word chain because the ordering of the letters is changed.
Constraints:
1 <= words.length <= 1000
1 <= words[i].length <= 16
words[i]
only consists of lowercase English letters.
Solution:
Algorithm:
- Sort words by word length in ascending order
- Initialize Hashmap H of type
string->int
- For each word find subwords (word-1 char) and check if subword is in H. Find the maximum possible value of
H[subword]
out of all subwords. Call itctr
. If there is no subword in H thenctr=0
H[word] = ctr+1
- Finally answer is the maximum of all values in
H
.
bool complen(string s1, string s2)
{
return s1.length() < s2.length();
}
class Solution {
public:
int longestStrChain(vector<string>& words) {
unordered_map<string,int> H;
int res=0;
sort(words.begin(), words.end(), complen);
for (string word: words)
{
int wn = word.length(), ctr=0;
for (int i=0; i<wn; i++)
{
string sub = string(word.begin(),word.begin()+i) +
string(word.begin()+i+1, word.end());
if (H.count(sub)) ctr=max(ctr,H[sub]);
}
H[word]=ctr+1;
res = max(res, H[word]);
}
return res;
}
};
TC: O(N*|S| + N*log(N))
SC: O(N)
where N=#(words)
, |S|=max length of word
Reasoning for TC:
N*|S|
term comes because for each word we are finding all the subwords
N*log(N)
term comes because we are doing a sorting operation in the beginning
Reasoning for SC: Size of HashMap is N.
PLEASE UPVOTE.