Problem Description
We are given an integer array (nums) whose entries are only 1, 2, or 3 and a binary array (locked) of the same length. We say that nums is “sortable” if one may repeatedly perform an adjacent swap between positions i and i+1 – but only when the number at position i is exactly one more than that at position i+1 AND when locked[i] is 0 – so that eventually nums becomes sorted in non‐decreasing order. In one “operation” you may pick any index i and “unlock” it (by setting locked[i] to 0). Return the minimum operations needed to make nums sortable; if even after unlocking any subset the required order can’t be reached then return –1.
Key Insights
- Only adjacent swaps where the left element is exactly 1 greater than the right element are allowed. (That is, you can swap a (2,1) or (3,2) but never a (3,1) directly.)
- Even if all indices are free the allowed “bubble‐sort” style moves are not powerful enough to realize an arbitrary permutation. In fact, the numbers in any “sortable” sequence must “balance” in a prefix–sense: as you scan from left to right the difference between counts (first 1 vs 2 and then 2 vs 3) must never become negative.
- The locked entries are “stuck” in place – they must satisfy the prefix “balance” condition by themselves. In other words, if a locked element causes a violation of the invariant then it must be unlocked.
- We can “fix” sorting impossibilities only by turning some locked indices into free ones. In the end, the free elements (whose multiset is fixed) must be re–ordered (by allowed swaps) and interleaved with the remaining locked ones so that the entire array can be “bubbled” to non–decreasing order.
- Because the numbers range only over {1,2,3} one may “simulate” the process by thinking in terms of cumulative counts (or “prefix differences”). In any prefix the count(1) must be at least the count(2) and the count(2) must be at least the count(3).
Space and Time Complexity
Time Complexity: O(n) – We scan and update prefix conditions in one or two passes. Space Complexity: O(n) – For storing auxiliary arrays (or O(1) additional space if done in place).
Solution
The key observation is that a necessary (and for this problem, nearly sufficient) condition for a sequence to be sortable via these very restricted swaps is that if you “simulate” the process by taking the final configuration, then as you read from left to right the cumulative frequencies must obey: (#1’s so far) – (#2’s so far) ≥ 0 and (#2’s so far) – (#3’s so far) ≥ 0. Since “locked” indices cannot change their order, if they alone (in order) violate these inequalities then there is no way to “fix” the overall ordering using allowed adjacent swaps – unless you free some of those indices. Thus the idea is to choose a minimum set of locked indices to unlock so that the locked “skeleton” (i.e. the sequence of indices whose locked flag remains 1) satisfies the prefix invariants. (Notice that the free indices are “malleable:” although only certain adjacent swaps are allowed, it turns out that if the multiset of free numbers satisfies the necessary “balance” then they can be re–ordered appropriately.) A dynamic programming (DP) or greedy strategy can be used. One may scan the array from left to right while “merging” the fixed locked numbers with the free ones available for interleaving. When a locked element would cause a violation (for example, adding a 2 when there isn’t a free or locked 1 “before” it so that the difference would go negative) then that locked element “must” be unlocked. The following outline shows one way to solve it: • Precompute the total frequencies of 1, 2, and 3. • Initialize two “counters:” one for the cumulative contribution of locked elements (in order) and one for the free elements (which may be “re–ordered” arbitrarily provided that overall the prefix invariant holds). • Walk through the array in order; at each locked index, try “inserting” its value into the locked‐skeleton. If by doing so one of the invariants would be broken (i.e. the locked count of 1’s becomes less than that of 2’s or the locked count of 2’s becomes less than that of 3’s) then it is optimal to “free” that index (increment the unlock operation count) so that its value is instead added to the free multiset. • Finally, check that the free multiset (which now comprises all originally free indices plus the ones you unlocked) is “sortable” on its own (its free counts can be arranged in non–decreasing order via allowed swaps – this is equivalent to having the free counts satisfy the prefix invariant when sorted). If after processing the array the locked–skeleton respects the invariants and the free multiset is sortable, then the total number of indices we unlocked is the answer; otherwise return –1. One potential pitfall is that the operations of “unlocking” must be chosen optimally – unlocking too many (or too few) indices might either be unnecessary or leave behind an unsolvable locked skeleton. The crux is to “simulate” the forming of a valid target order by conservatively “freeing” any locked element that would force the prefix “imbalance.”