Remove shortest subarray to sort array
Company: Apple
Role: Data Scientist
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates proficiency in array algorithms, algorithmic efficiency (linear time and constant-space reasoning), and handling edge cases related to non-decreasing order, within the Coding & Algorithms domain.
Part 1: Minimum length of a removable subarray
Constraints
- 0 <= len(nums) <= 2 * 10^5
- -10^9 <= nums[i] <= 10^9
Examples
Input: ([1, 2, 3],)
Expected Output: 0
Explanation: The array is already non-decreasing, so removing an empty subarray is optimal.
Input: ([5, 4, 3, 2, 1],)
Expected Output: 4
Explanation: Any remaining non-decreasing array can contain at most one element, so the minimum removal length is 4.
Hints
- Find the longest non-decreasing prefix and the longest non-decreasing suffix.
- After that, use two pointers to see how cheaply you can connect a prefix element to a suffix element.
Part 2: Lexicographically smallest optimal removal pair
Constraints
- 1 <= len(nums) <= 2 * 10^5
- -10^9 <= nums[i] <= 10^9
Examples
Input: ([1, 2, 2, 3],)
Expected Output: [-1, -1]
Explanation: The array is already non-decreasing, so no removal is necessary.
Input: ([1, 5, 6, 2, 3, 4],)
Expected Output: [1, 2]
Explanation: Removing nums[1..2] = [5, 6] leaves [1, 2, 3, 4], which is non-decreasing. No removal of length 1 works.
Hints
- First compute the minimum removable length using the same prefix-suffix idea as in Part 1.
- Once the optimal length is known, scan L from left to right; the first valid segment of that length is the lexicographically smallest answer.
Part 3: Shortest removal from a chunked stream
Constraints
- 0 <= len(chunks) <= 2 * 10^5
- 0 <= sum(len(chunk) for chunk in chunks) <= 2 * 10^5
- -10^9 <= value <= 10^9 for every streamed value
Examples
Input: ([[1, 2], [], [2, 3, 4]],)
Expected Output: 0
Explanation: The full stream is [1, 2, 2, 3, 4], which is already non-decreasing.
Input: ([[1, 2, 3], [10, 4, 2], [3, 5]],)
Expected Output: 3
Explanation: The full stream is [1, 2, 3, 10, 4, 2, 3, 5]. Removing [10, 4, 2] leaves [1, 2, 3, 3, 5], which is non-decreasing.
Hints
- Store the starting global index of each non-empty chunk so you can map a global position back to its chunk.
- Compared with fully flattening, chunk-boundary metadata saves memory but makes random access a bit slower.
Part 4: Array repair follow-up toolkit
Constraints
- 0 <= len(nums) <= 2 * 10^5
- mode is one of 'verify', 'strict', 'k'
- For mode 'verify', extra has length 2 and may be [-1, -1]
- For mode 'k', extra has length 1 and 0 <= k <= len(nums)
- -10^9 <= nums[i] <= 10^9
Examples
Input: ([1, 2, 10, 3, 4], [2, 2])
Expected Output: 1
Explanation: Removing only 10 gives [1, 2, 3, 4], which is non-decreasing, and length 1 is optimal.
Input: ([1, 2, 10, 3, 4], [1, 3])
Expected Output: 0
Explanation: Removing [2, 10, 3] leaves [1, 4], which is valid, but length 3 is not shortest because length 1 already works.
Hints
- For the strict variant, reuse the same prefix-suffix two-pointer idea but replace <= with < everywhere.
- For the k-deletions variant, think about the longest non-decreasing subsequence: if its length is L, then n - L deletions are enough and also necessary.