3302. Find the Lexicographically Smallest Valid Sequence
Description
You are given two strings word1 and word2.
A string x is called almost equal to y if you can change at most one character in x to make it identical to y.
A sequence of indices seq is called valid if:
- The indices are sorted in ascending order.
- Concatenating the characters at these indices in
word1in the same order results in a string that is almost equal toword2.
Return an array of size word2.length representing the lexicographically smallest valid sequence of indices. If no such sequence of indices exists, return an empty array.
Note that the answer must represent the lexicographically smallest array, not the corresponding string formed by those indices.
Example 1:
Input: word1 = "vbcca", word2 = "abc"
Output: [0,1,2]
Explanation:
The lexicographically smallest valid sequence of indices is [0, 1, 2]:
- Change
word1[0]to'a'. word1[1]is already'b'.word1[2]is already'c'.
Example 2:
Input: word1 = "bacdc", word2 = "abc"
Output: [1,2,4]
Explanation:
The lexicographically smallest valid sequence of indices is [1, 2, 4]:
word1[1]is already'a'.- Change
word1[2]to'b'. word1[4]is already'c'.
Example 3:
Input: word1 = "aaaaaa", word2 = "aaabc"
Output: []
Explanation:
There is no valid sequence of indices.
Example 4:
Input: word1 = "abc", word2 = "ab"
Output: [0,1]
Constraints:
1 <= word2.length < word1.length <= 3 * 105word1andword2consist only of lowercase English letters.
Solutions
Solution 1: Greedy + Two Pointers
We first use two pointers to preprocess a suffix array \(\textit{suf}\) from right to left, where \(\textit{suf}[i]\) represents the smallest starting index in \(\textit{word2}\) such that \(\textit{word2}[\textit{suf}[i]:]\) is a subsequence of \(\textit{word1}[i:]\). Specifically, we use a pointer \(j\) pointing to the frontmost unmatched character in \(\textit{word2}\), initially \(j = n - 1\), and set \(\textit{suf}[m] = n\). Starting from \(i = m - 1\), we traverse \(\textit{word1}\) from right to left. If \(j \ge 0\) and \(\textit{word1}[i] = \textit{word2}[j]\), it means \(\textit{word2}[j]\) can be matched, so we decrement \(j\) by one, and then set \(\textit{suf}[i] = j + 1\).
Next, we traverse \(\textit{word1}\) from left to right, using a pointer \(j\) to denote the index of the character in \(\textit{word2}\) that we currently need to match (initially \(j = 0\)), and a variable \(\textit{changed}\) to record whether we have already modified a character. For each character \(c\) at index \(i\):
- If \(c = \textit{word2}[j]\), choosing index \(i\) is always no worse (the smaller the index, the smaller the lexicographical order of the sequence), so we directly add \(i\) to the answer and increment \(j\) by one;
- Otherwise, if we have not modified a character yet and \(\textit{suf}[i+1] \le j + 1\), it means we can modify \(\textit{word1}[i]\) to \(\textit{word2}[j]\), and the remaining part \(\textit{word2}[j+1:]\) can still be matched within \(\textit{word1}[i+1:]\). In this case, we choose index \(i\) and set \(\textit{changed}\) to true.
When \(j = n\), we have matched all of \(\textit{word2}\) and can return the answer. If the traversal ends without completing the match, we return an empty array.
The time complexity is \(O(m + n)\), and the space complexity is \(O(m)\), where \(m\) and \(n\) are the lengths of the strings \(\textit{word1}\) and \(\textit{word2}\), respectively.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
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 | |
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 | |
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 | |
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 | |
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 | |