-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path1048-Longest_String_Chain.cpp
More file actions
130 lines (118 loc) · 3.54 KB
/
1048-Longest_String_Chain.cpp
File metadata and controls
130 lines (118 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*******************************************************************************
* 1048-Longest_String_Chain.cpp
* Billy.Ljm
* 23 September 2023
*
* =======
* Problem
* =======
* https://leetcode.com/problems/longest-string-chain/
*
* 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.
*
* ===========
* My Approach
* ===========
* Every predecessor will be one character shorter than its successor. Thus, we
* can iterate through the strings of ascending lengths, calculating the longest
* word chain ending with each string. If the new string has predecessors, then
* its maximum chain length will be the max of its predecessors plus one.
* Otherwise the new string will form a single-element chain.
*
* This has a time complexity of O(n^2), and a space complexity of O(n), where
* n is the number of words
******************************************************************************/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/**
* << operator for vectors
*/
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
os << "[";
for (const auto elem : v) {
os << elem << ",";
}
if (v.size() > 0) os << "\b";
os << "]";
return os;
}
/**
* Solution
*/
class Solution {
private:
/**
* Check is pred is a predcessor of succ
*/
bool checkPred(string pred, string succ) {
int offset = 0;
for (int i = 0; i < pred.length(); i++) {
while (pred[i] != succ[i + offset]) {
offset++;
if (offset > 1) return false;
}
}
return true;
}
public:
int longestStrChain(vector<string>& words) {
// sort in asceding string length
sort(words.begin(), words.end(),
[](const string lhs, const string rhs) {
return lhs.length() < rhs.length();
});
// count max chain ending with each char
vector<int> maxchain(words.size(), 1);
for (int i = 1; i < words.size(); i++) {
int maxpred = 0; // max chain length of predcessors
// find all possible predecessors
for (int j = i - 1; j >= 0; j--) {
if (words[j].length() < words[i].length() - 1) break;
else if (words[j].length() == words[i].length()) continue;
if (checkPred(words[j], words[i])) {
maxchain[i] = max(maxchain[i], maxchain[j] + 1);
}
}
}
// find max chain ending with any char
return *max_element(maxchain.begin(), maxchain.end());
}
};
/**
* Test cases
*/
int main(void) {
Solution sol;
vector<string> words;
// test case 1
words = { "a","b","ba","bca","bda","bdca" };
std::cout << "longestStrChain(" << words << ") = ";
std::cout << sol.longestStrChain(words) << std::endl;
// test case 2
words = { "xbc","pcxbcf","xb","cxbc","pcxbc" };
std::cout << "longestStrChain(" << words << ") = ";
std::cout << sol.longestStrChain(words) << std::endl;
// test case 3
words = { "abcd","dbqca" };
std::cout << "longestStrChain(" << words << ") = ";
std::cout << sol.longestStrChain(words) << std::endl;
return 0;
}