Watch 6 video solutions for Transform Binary String Using Subsequence Sort, a medium level problem. This walkthrough by CodeSprint has 466 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
You are given a binary string s.
You are also given an array of strings strs, where each strs[i] has the same length as s and consists of characters '0', '1', and '?'. Each '?' can be replaced by either '0' or '1'.
You may perform the following operation any number of times (including zero):
sub of s.sub in non-decreasing order.s with the sorted sub, keeping all other characters unchanged.Return a boolean array ans, where ans[i] is true if it's possible to replace all '?' in strs[i] with '0' or '1' and transform s into the resulting string using the allowed operation above, otherwise return false.
Example 1:
Input: s = "101", strs = ["1?1","0?1","0?0"]
Output: [true,true,false]
Explanation:
i |
strs[i] |
Replacement | Result strs[i] |
Operation(s) | Result |
|---|---|---|---|---|---|
| 0 | "1?1" |
? → 0 |
"101" |
Matches s. |
true |
| 1 | "0?1" |
? → 1 |
"011" |
Select the subsequence at indices [0..2] of s → "101".Sort "101" to get "011" = strs[i]. |
true |
| 2 | "0?0" |
? → 0 or 1 |
"000" or "010" |
Not feasible. | false |
Thus, ans = [true, true, false].
Example 2:
Input: s = "1100", strs = ["0011","11?1","1?1?"]
Output: [true,false,true]
Explanation:
i |
strs[i] |
Replacement | Result strs[i] |
Operation(s) | Result |
|---|---|---|---|---|---|
| 0 | "0011" |
- | "0011" |
Select the subsequence at indices [0..3] of s → "1100".Sort "1100" to get "0011" = strs[i]. |
true |
| 1 | "11?1" |
? → 0 |
"1101" |
Not feasible. | false |
| 2 | "1?1?" |
First ? → 0Second ? → 0 |
"1010" |
Select the subsequence at indices [1, 2] of s → "10".Sort "10" to get "01", so s = "1010". |
true |
Thus, ans = [true, false, true].
Example 3:
Input: s = "1010", strs = ["0011"]
Output: [true]
Explanation:
i |
strs[i] |
Replacement | Result strs[i] |
Operation(s) | Result |
|---|---|---|---|---|---|
| 0 | "0011" |
- | "0011" |
Select the subsequence at indices [0, 2, 3] of s → "110".Sort "110" to get "011", so s = "0011" = strs[i]. |
true |
Thus, ans = [true].
Constraints:
1 <= n == s.length <= 2000s[i] is either '0' or '1'.1 <= strs.length <= 2000strs[i].length == nstrs[i] is either '0', '1', or '?'āāāāāāā.Problem Overview: You need to transform a binary string into its sorted form using operations performed on subsequences. The challenge is identifying the minimum number of operations while preserving the relative constraints imposed by subsequence selection.
Approach 1: Brute Force Simulation (O(n2) time, O(n) space)
The direct approach simulates every possible subsequence operation and checks whether the string becomes sorted after each transformation. You iterate through all indices, collect misplaced characters, and repeatedly apply subsequence sorting until the string stabilizes. This works for small inputs because every operation explicitly rebuilds part of the string. The main drawback is repeated scanning and reconstruction, which makes it quadratic for larger inputs.
Approach 2: Greedy Counting with Two Pointers (O(n) time, O(1) space)
The optimal solution relies on a key observation: a binary string is already sorted if every 0 appears before every 1. You can scan the string once and track inversions where a 1 appears before a later 0. Using two pointers from both ends, or a single pass with counters, you identify the minimum subsequence adjustments needed without physically sorting after every operation. This avoids unnecessary reconstruction and reduces the runtime to linear complexity.
The greedy idea works because subsequence sorting can fix multiple misplaced characters in a single operation. Instead of thinking about individual swaps, you count how many groups of invalid ordering exist. Problems involving binary strings often reduce to counting transitions or inversions rather than simulating edits directly. Similar optimization patterns appear in greedy algorithms and two pointers problems.
Approach 3: Stack or Index Tracking Variant (O(n) time, O(n) space)
Another implementation keeps indices of misplaced 1s inside a stack or array. When a 0 appears after them, you match positions and determine whether the current subsequence operation can absorb multiple corrections. This version is easier to reason about during interviews because every mismatch is explicitly represented. The tradeoff is extra memory usage compared to the pure greedy counter approach.
Most interviewers expect the linear greedy solution because the constraints usually make quadratic simulation too slow. Showing the brute force approach first demonstrates that you understand the operation mechanics. Moving to the optimized pass shows that you can extract the invariant behind the transformation process. Problems like this commonly test pattern recognition in string algorithms rather than advanced data structures.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Simulation | O(n²) | O(n) | Useful for understanding subsequence operations or very small inputs |
| Greedy Counting with Two Pointers | O(n) | O(1) | Best general solution for interviews and competitive programming |
| Stack or Index Tracking | O(n) | O(n) | Helpful when you want explicit mismatch tracking for debugging |