Skip to main content

Find the Lexicographically Smallest Valid Sequence - Solution & Explanation

Practice this problem

Problem Statement

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 word1 in the same order results in a string that is almost equal to word2.

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 * 105
  • word1 and word2 consist only of lowercase English letters.

Approach Overview

Problem Overview: You are given two strings and must return a sequence of indices from the first string that forms the second string while keeping the sequence lexicographically smallest. The challenge is not just finding a valid subsequence, but ensuring the earliest possible indices are chosen while still allowing the rest of the pattern to be completed.

Approach 1: Two-Pointer with Backtracking (O(n + m) average, O(m) space)

This approach scans the source string using two pointers. One pointer iterates through the main string while the other tracks progress through the target pattern. When characters match, record the index and advance both pointers. If a later mismatch would prevent completing the pattern, backtracking allows adjusting previously chosen indices to keep the sequence valid while maintaining lexicographic minimality. The key insight is that greedy forward matching works most of the time, while minimal backtracking corrects early decisions when the suffix cannot be formed. This technique relies heavily on two pointers and efficient string traversal.

Approach 2: Greedy with Sorting on Indices (O(n log n) time, O(n) space)

The greedy approach precomputes candidate positions for each character of the pattern inside the source string. These indices are collected and processed so that the smallest feasible index is always chosen first. Sorting candidate positions ensures lexicographic ordering, while validation checks confirm that enough characters remain to finish the sequence. The main idea is that choosing the earliest valid index preserves lexicographic order as long as the remaining suffix is still achievable. This strategy combines greedy decision making with structured index management.

Approach 3: Dynamic Programming Feasibility Check (O(n * m) time, O(m) space)

A dynamic programming helper can verify whether the remaining suffix of the pattern can still be matched after selecting a candidate index. The DP state tracks how many characters of the pattern can be matched from a given suffix of the main string. During greedy selection, this feasibility check prevents picking an index that would block completion of the sequence. Although slower than the pointer-based approach, it provides a clear correctness guarantee and demonstrates the relationship between subsequence matching and dynamic programming.

Recommended for interviews: The two-pointer greedy strategy is usually what interviewers expect. It shows you understand subsequence construction, lexicographic ordering, and how to maintain feasibility while scanning a string once. Mentioning the DP feasibility idea demonstrates deeper reasoning, but implementing the optimized two-pointer solution proves stronger algorithmic skill.

Approach 1: Two-Pointer with Backtracking

This approach utilizes a two-pointer technique combined with backtracking. The idea is to align two pointers, one on word1 and the other on word2. Whenever a mismatch occurs, explore the possibility of changing a character in word1 to align with word2. Keep track of the smallest lexicographical indices that form a valid sequence.

The solution defines a recursive backtracking function to explore all paths for matching word2 in word1. It uses memoization to avoid recomputation. Changes are only allowed to make a character match. The base cases handle the end of the search, with successful and unsuccessful path handling. The lexicographically smallest path is tracked and returned.

Code

Python

JavaScript

Complexity

The time complexity is O(n * m), where n is the length of word1 and m is the length of word2. The space complexity is O(n * m) due to memoization storage.

Try this approach in the editor →

Approach 2: Greedy with Sorting on Indices

In this approach, use a greedy technique combined with sorting. Iterate through each character in word1, checking potential matches or almost matches with word2. Ensure the sequence of chosen indices is sorted and minimal modifications are enforced.

This Java implementation iteratively tries to form word2 from different starting positions in word1. It checks if the sequence can be made almost equal with at most one modification. Among feasible options, it selects the lexicographically smallest sequence using the helper method lexicographicallySmaller.

Code

Java

C++

Complexity

The time complexity is O(n * m), caused by checking each index and potential index sequence in word1 against word2. Space complexity is O(m) for storing the indices.

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
Two-Pointer with Backtracking

The time complexity is O(n * m), where n is the length of word1 and m is the length of word2. The space complexity is O(n * m) due to memoization storage.

Greedy with Sorting on Indices

The time complexity is O(n * m), caused by checking each index and potential index sequence in word1 against word2. Space complexity is O(m) for storing the indices.

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Two-Pointer with BacktrackingO(n + m) averageO(m)Best general solution for subsequence matching while preserving lexicographic order
Greedy with Sorting on IndicesO(n log n)O(n)Useful when candidate indices for each character are precomputed
Dynamic Programming Feasibility CheckO(n * m)O(m)Good for understanding subsequence feasibility or verifying greedy choices

Video Solution

Leetcode Biweekly Contest 140 | 3302. Find the Lexicographically Smallest Valid Sequence | GreedyCodeFod2,255 views views

Watch 4 more video solutions →

Frequently Asked Questions

Is Find the Lexicographically Smallest Valid Sequence easy or hard?
The problem is rated Medium because the subsequence matching itself is straightforward, but maintaining lexicographic minimality while ensuring the remaining pattern can still be formed requires careful greedy reasoning. Candidates who understand two-pointer subsequence techniques usually solve it efficiently.
Find the Lexicographically Smallest Valid Sequence Python/Java solution
Python solutions typically implement the greedy two-pointer scan with a list storing chosen indices. Java or C++ implementations often use arrays or ArrayList structures while scanning the string once. Both versions follow the same algorithmic idea and achieve O(n + m) time complexity.
How to solve Find the Lexicographically Smallest Valid Sequence in O(n)?
Scan the source string with a pointer while tracking the pattern with another pointer. When characters match, record the index and advance both pointers. Ensure the remaining suffix of the source still contains enough characters to complete the pattern. This greedy subsequence construction produces the lexicographically smallest valid index sequence in linear time.
What is the best approach for Find the Lexicographically Smallest Valid Sequence?
The most efficient approach uses a greedy two-pointer scan of the source string while tracking the progress of the target pattern. Each match records the earliest possible index, ensuring lexicographic minimality. Backtracking or feasibility checks ensure the remaining characters can still form the pattern. This approach typically runs in O(n + m) time with O(m) space.
Is Find the Lexicographically Smallest Valid Sequence asked at Google/Amazon/Meta?
Problems involving lexicographically smallest subsequences, greedy string matching, and index reconstruction appear frequently in interviews at companies like Google, Amazon, and Meta. Variants of this problem test understanding of subsequences, greedy decisions, and pointer-based string processing.
What data structure is used in Find the Lexicographically Smallest Valid Sequence?
The solution mainly relies on arrays or lists to store the resulting indices, along with two-pointer traversal of the strings. Some implementations also maintain sorted lists of candidate indices or prefix/suffix arrays for feasibility checks.
What is the time complexity of Find the Lexicographically Smallest Valid Sequence?
The optimal solution using a two-pointer greedy strategy runs in O(n + m) time, where n is the length of the main string and m is the length of the pattern. Alternative implementations that manage candidate indices with sorting may run in O(n log n). A dynamic programming feasibility version can take O(n * m).

Ready to solve this problem?

Practice Find the Lexicographically Smallest Valid Sequence with our built-in code editor and test cases.

Practice on FleetCode