1574. Shortest Subarray to be Removed to Make Array Sorted
Description
Given an integer array arr, remove a subarray (can be empty) from arr such that the remaining elements in arr are non-decreasing.
Return the length of the shortest subarray to remove.
A subarray is a contiguous subsequence of the array.
Example 1:
Input: arr = [1,2,3,10,4,2,3,5] Output: 3 Explanation: The shortest subarray we can remove is [10,4,2] of length 3. The remaining elements after that will be [1,2,3,3,5] which are sorted. Another correct solution is to remove the subarray [3,10,4].
Example 2:
Input: arr = [5,4,3,2,1] Output: 4 Explanation: Since the array is strictly decreasing, we can only keep a single element. Therefore we need to remove a subarray of length 4, either [5,4,3,2] or [4,3,2,1].
Example 3:
Input: arr = [1,2,3] Output: 0 Explanation: The array is already non-decreasing. We do not need to remove any elements.
Constraints:
1 <= arr.length <= 1050 <= arr[i] <= 109
Solutions
Solution 1: Two Pointers + Binary Search
Thinking
Delete one contiguous subarray so the rest is nondecreasing, and minimize the deletion. \(n\le 10^5\) forbids trying every interval. What remains is a prefix plus a suffix whose join is still sorted.
Find the longest nondecreasing prefix \([0,i]\) and suffix \([j,n)\). If they already cover the array the answer is \(0\); otherwise we may drop the whole suffix or the whole prefix. For each prefix end \(l\), binary-search the first suffix index \(r\) with \(arr[r]\ge arr[l]\), delete \((l,r)\), and keep the shortest.
First, we find the longest non-decreasing prefix and the longest non-decreasing suffix of the array, denoted as \(\textit{nums}[0..i]\) and \(\textit{nums}[j..n-1]\), respectively.
If \(i \geq j\), it means the array is already non-decreasing, so we return \(0\).
Otherwise, we can choose to delete the right suffix or the left prefix. Therefore, initially, the answer is \(\min(n - i - 1, j)\).
Next, we enumerate the right endpoint \(l\) of the left prefix. For each \(l\), we can use binary search to find the first position greater than or equal to \(\textit{nums}[l]\) in \(\textit{nums}[j..n-1]\), denoted as \(r\). At this point, we can delete \(\textit{nums}[l+1..r-1]\) and update the answer \(\textit{ans} = \min(\textit{ans}, r - l - 1)\). Continue enumerating \(l\) to get the final answer.
The time complexity is \(O(n \times \log n)\), where \(n\) is the length of the array. The space complexity is \(O(1)\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
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 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Solution 2: Two Pointers
Thinking
Solution 1 binary-searches each \(l\) and pays an extra \(\log n\). Both sides are sorted, so \(r\) only moves right as \(l\) grows. A monotone right pointer makes the second loop linear.
Similar to Solution 1, we first find the longest non-decreasing prefix and the longest non-decreasing suffix of the array, denoted as \(\textit{nums}[0..i]\) and \(\textit{nums}[j..n-1]\), respectively.
If \(i \geq j\), it means the array is already non-decreasing, so we return \(0\).
Otherwise, we can choose to delete the right suffix or the left prefix. Therefore, initially, the answer is \(\min(n - i - 1, j)\).
Next, we enumerate the right endpoint \(l\) of the left prefix. For each \(l\), we directly use two pointers to find the first position greater than or equal to \(\textit{nums}[l]\) in \(\textit{nums}[j..n-1]\), denoted as \(r\). At this point, we can delete \(\textit{nums}[l+1..r-1]\) and update the answer \(\textit{ans} = \min(\textit{ans}, r - l - 1)\). Continue enumerating \(l\) to get the final answer.
The time complexity is \(O(n)\), where \(n\) is the length of the array. The space complexity is \(O(1)\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
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 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |