Skip to content

Latest commit

 

History

History

2901

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

You are given an integer n, a 0-indexed string array words, and a 0-indexed array groups, both arrays having length n.

The hamming distance between two strings of equal length is the number of positions at which the corresponding characters are different.

You need to select the longest subsequence from an array of indices [0, 1, ..., n - 1], such that for the subsequence denoted as [i0, i1, ..., ik - 1] having length k, the following holds:

  • For adjacent indices in the subsequence, their corresponding groups are unequal, i.e., groups[ij] != groups[ij + 1], for each j where 0 < j + 1 < k.
  • words[ij] and words[ij + 1] are equal in length, and the hamming distance between them is 1, where 0 < j + 1 < k, for all indices in the subsequence.

Return a string array containing the words corresponding to the indices (in order) in the selected subsequence. If there are multiple answers, return any of them.

A subsequence of an array is a new array that is formed from the original array by deleting some (possibly none) of the elements without disturbing the relative positions of the remaining elements.

Note: strings in words may be unequal in length.

 

Example 1:

Input: n = 3, words = ["bab","dab","cab"], groups = [1,2,2]
Output: ["bab","cab"]
Explanation: A subsequence that can be selected is [0,2].
- groups[0] != groups[2]
- words[0].length == words[2].length, and the hamming distance between them is 1.
So, a valid answer is [words[0],words[2]] = ["bab","cab"].
Another subsequence that can be selected is [0,1].
- groups[0] != groups[1]
- words[0].length == words[1].length, and the hamming distance between them is 1.
So, another valid answer is [words[0],words[1]] = ["bab","dab"].
It can be shown that the length of the longest subsequence of indices that satisfies the conditions is 2.  

Example 2:

Input: n = 4, words = ["a","b","c","d"], groups = [1,2,3,4]
Output: ["a","b","c","d"]
Explanation: We can select the subsequence [0,1,2,3].
It satisfies both conditions.
Hence, the answer is [words[0],words[1],words[2],words[3]] = ["a","b","c","d"].
It has the longest length among all subsequences of indices that satisfy the conditions.
Hence, it is the only answer.

 

Constraints:

  • 1 <= n == words.length == groups.length <= 1000
  • 1 <= words[i].length <= 10
  • 1 <= groups[i] <= n
  • words consists of distinct strings.
  • words[i] consists of lowercase English letters.

Companies: fourkites

Related Topics:
Array, String, Dynamic Programming

Hints:

  • Let dp[i] represent the length of the longest subsequence ending with words[i] that satisfies the conditions.
  • dp[i] = (maximum value of dp[j]) + 1 for indices j < i, where groups[i] != groups[j], words[i] and words[j] are equal in length, and the hamming distance between words[i] and words[j] is exactly 1.
  • Keep track of the j values used to achieve the maximum dp[i] for each index i.
  • The expected array's length is max(dp[0:n]), and starting from the index having the maximum value in dp, we can trace backward to get the words.

Solution 1. DP

// OJ: https://leetcode.com/problems/longest-unequal-adjacent-groups-subsequence-ii
// Author: github.com/lzl124631x
// Time: O(N^2)
// Space: O(N)
class Solution {
public:
    vector<string> getWordsInLongestSubsequence(int n, vector<string>& A, vector<int>& G) {
        vector<int> len(n + 1, 1), prev(n + 1, -1);
        auto hammingDistance = [&](int i, int j) {
            int cnt = 0;
            for (int k = 0; k < A[i].size(); ++k) {
                cnt += A[i][k] != A[j][k];
            }
            return cnt;
        };
        int maxLen = 0, best = -1;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < i; ++j) {
                if (G[i] == G[j] || A[i].size() != A[j].size() || hammingDistance(i, j) != 1) continue;
                if (len[j] + 1 > len[i]) {
                    len[i] = len[j] + 1;
                    prev[i] = j;
                }
            }
            if (len[i] > maxLen) {
                maxLen = len[i];
                best = i;
            }
        }
        vector<string> ans;
        while (best != -1) {
            ans.push_back(A[best]);
            best = prev[best];
        }
        reverse(begin(ans), end(ans));
        return ans;
    }
};