2901: Longest-Unequal-Adjacent-Groups-Subsequence-II
Medium
table of contents
This question is just a dynamic programming question.
My first thought is, for any index i, if the
longest subsequence that ends at the index
i is greater than 1, then the previous word
must be located in words at an index value between
[0, i). However, then the problem is, how do you know how
many previous words existed in this specific sequence of
words.
We can do this using an array of size n that I called
dp. In it, at each index i, we hold the:
Then, at index i, we can simply check which of the
elements at indices smaller than i have a hamming
distance of 1. Now, using the dp
array, we can determine which subsequence (ending at indices containing
values with a hamming distance of 1 to
i) we want to append words[i] to (the
longest one) and the index of the previous element.
Finally, we can simply just repeat this until we reach the element and backtrack from the tail-end of the longest subsequence.
code
struct dpElement {
int maxSubsequenceLength;
int prevElementIndex;
dpElement(int length = -1, int prev = -1)
: maxSubsequenceLength(length), prevElementIndex(prev) { }
};
class Solution {
public:
vector<string> getWordsInLongestSubsequence(vector<string>& words, vector<int>& groups) {
vector<dpElement> dp (words.size());
int maxSubsequenceLength{1};
int maxSubsequenceIndex{0};
dp[0] = dpElement(1, -1);
for (int i = 1; i < words.size(); ++i) {
dpElement tempElement = dpElement();
for (int j = 0; j < i; ++j) {
if (groups[i] == groups[j]) continue;
if (dp[j].maxSubsequenceLength < tempElement.maxSubsequenceLength) continue;
if (words[i].size() != words[j].size()) continue;
int diff = 0;
for (int k = 0; diff < 2 && k < min(words[i].size(), words[j].size()); ++k) {
if (words[i][k] != words[j][k]) {
++diff;
}
}
if (diff < 2) {
tempElement.prevElementIndex = j;
tempElement.maxSubsequenceLength = dp[j].maxSubsequenceLength+1;
}
}
if (tempElement.maxSubsequenceLength > maxSubsequenceLength) {
maxSubsequenceLength = tempElement.maxSubsequenceLength;
maxSubsequenceIndex = i;
}
if (tempElement.maxSubsequenceLength == -1) tempElement.maxSubsequenceLength = 1;
dp[i] = tempElement;
}
vector<string> ans (maxSubsequenceLength);
for (int i = maxSubsequenceLength-1; i >= 0; --i) {
ans[i] = words[maxSubsequenceIndex];
maxSubsequenceIndex = dp[maxSubsequenceIndex].prevElementIndex;
}
return ans;
}
};