Shortest Subarray to be Removed to Make Array Sorted

Updated on 11 July, 2025
Shortest Subarray to be Removed to Make Array Sorted header image

Problem Statement

In the given problem, we are asked to handle an integer array named arr. The goal is to adjust this array so that it becomes a non-decreasing sequence. The adjustment is made by removing a contiguous sub-sequence (subarray) from the original array. Our task is to determine the minimum length of such a subarray that, when removed, will render the rest of the array non-decreasing. This length is what we need to return.

To clarify, a non-decreasing array is one in which each element is equal to or larger than the one that precedes it. The term "subarray" referred in the problem specifies a contiguous segment of the array which means the elements are consecutive in terms of their indices. An empty subarray, indicating no changes, is permissible if the array is already non-decreasing.

Examples

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 <= 105
  • 0 <= arr[i] <= 109

Approach and Intuition

The solution involves several steps and insights:

  1. Observing Boundaries:

    • Identify the points in the array where the property of being non-decreasing is violated. This gives a clear indication of where potential removals might start or end.
  2. Finding Extremes:

    • Scan from the left of the array and find where the sequence starts to decrease.
    • Similarly, scan from the right to identify where the sequence stops increasing.
  3. Assess Overlaps:

    • With identified starting and ending points of increasing sequences from both ends, assess the potential cuts. These include not only cutting one side entirely but also combinations where partial sequences from both ends are retained.
  4. Compute Minimum Cut Length:

    • The goal is to minimize the removed subarray’s length. Therefore, for each viable cut calculated from the overlap assessments, we keep track of the minimum length observed.
  5. Edge Cases Handling:

    • The situation where the entire array is non-decreasing needs special handling—return 0 in this case as no removal is needed.
    • Also, for arrays already in a strictly decreasing order (the worst case), handle efficiently to return the length minus one, since keeping any single element maintains the non-decreasing order.

Intuition Behind the Example

  • For the array [1,2,3,10,4,2,3,5]:
    • A clear issue starts after '3' which increases to '10' then followed by '4' and '2' that are decreasing. This discontinuity invites the focus on possibly removing elements around '10', '4', and '2'.
    • The investigation here would involve considering cuts just after '3' or starting right before '5', ensuring the rest of the elements on either side form a non-decreasing sequence.
    • This line of reasoning brings forward the minimum cut length.

In summary, the solution requires scanning and analyzing the array from both ends, computing viable cut points through overlaps, and determining the shortest subarray that can be removed to establish or maintain the non-decreasing order. The examples given illustrate these principles through practical scenarios, reinforcing the strategy of dual scanning and evaluating overlaps for minimal removal.

Solutions

  • C++
cpp
class Solution {
public:
    int minimalSubarrayRemove(vector<int>& nums) {
        int end = nums.size() - 1;
        while (end > 0 && nums[end] >= nums[end - 1]) {
            end--;
        }
    
        int result = end;
        int begin = 0;
        while (begin < end && (begin == 0 || nums[begin - 1] <= nums[begin])) {
            while (end < nums.size() && nums[begin] > nums[end]) {
                end++;
            }
            result = min(result, end - begin - 1);
            begin++;
        }
        return result;
    }
};

To solve the problem of finding the shortest subarray to be removed to make an array sorted, you will implement a C++ solution that essentially optimizes the search through both ends of the array. Follow a dual-pointer approach to efficiently pinpoint the minimal section that once removed will result in a sorted array.

  1. Define the last index end of the array to start at nums.size() - 1. Iterate backwards to find the first disorder where nums[end] < nums[end - 1].

  2. Establish a variable result initiated to the value of end. This variable traces the shortest subarray length to be removed.

  3. Initialize a pointer begin at the start of the array. Confirm each element respects the order condition by proceeding in the array as long as nums[begin - 1] <= nums[begin].

  4. For each position at begin, use the second pointer end. Increment end to skip over any elements that violate the sorted order due to being less than nums[begin].

  5. Update result with the minimum value found between the current result and end - begin - 1, which calculates the new potential minimal subarray length.

  6. After exiting the loops, return the smallest value of result computed, which represents the size of the shortest subarray that must be removed.

This method leverages a combination of optimization check points and minimizes unnecessary computations by promptly adjusting pointers, ensuring a swift and thorough examination of potential subarrays in the array. The dual navigation through the array from both ends helps accurately pinpoint the subarray to ensure the entire array's sort order once it is removed.

  • Java
java
class Solution {
    
    public int minimumDeletedSubarrayLength(int[] data) {
        int end = data.length - 1;
        while (end > 0 && data[end] >= data[end - 1]) {
            end--;
        }
    
        int minLength = end;
        int start = 0;
        while (start < end && (start == 0 || data[start - 1] <= data[start])) {
            while (end < data.length && data[start] > data[end]) {
                end++;
            }
            minLength = Math.min(minLength, end - start - 1);
            start++;
        }
        return minLength;
    }
}

This Java solution focuses on finding the shortest subarray that, when removed, results in an array sorted in non-decreasing order. Examine the key points of the solution:

  • Initialize end to point to the last index of the array and decrement it as long as the elements are in non-decreasing order from the end of the array.

  • Set minLength to the value of end after the loop, which provides the count of elements that are out of order from the end.

  • Use a loop starting from the beginning of the array to check further possibilities of removing shorter subarrays. Increment start provided the array elements from the start maintain non-decreasing order.

  • For each valid position of start, if data[start] is greater than data[end], increment end until data[start] is no longer greater than data[end]. This increases the size of the potential subarray to be removed.

  • Update minLength to be the minimum of its current value and end - start - 1, which is the length of the current subarray that could potentially be removed to make the array sorted.

  • The loop continues until all starting positions have been checked against possible ending positions to find the minimum length of a subarray that can be removed.

  • The function ends by returning minLength, which by this time holds the length of the shortest subarray removal that ensures the remaining array elements are in sorted order.

By utilizing two pointers, start and end, the solution efficiently determines the minimal subarray removal requirement while iterating through the array a minimal number of times.

  • Python
python
class Solution:
    def minimumSubarrayDeletion(self, array: List[int]) -> int:
        right_index = len(array) - 1
        while right_index > 0 and array[right_index] >= array[right_index - 1]:
            right_index -= 1
    
        result = right_index
        left_index = 0
        while left_index < right_index and (left_index == 0 or array[left_index - 1] <= array[left_index]):
            while right_index < len(array) and array[left_index] > array[right_index]:
                right_index += 1
            result = min(result, right_index - left_index - 1)
            left_index += 1
        return result

The solution provided involves finding the minimum length of a subarray which, when removed from a given array, results in the remaining elements of the array being sorted in non-decreasing order. This Python function named minimumSubarrayDeletion employs a two-pointer technique to solve the problem efficiently.

  • Start by initializing right_index to point to the last element of the array. Traverse backwards to find the last index where the elements are in descending order.
  • Establish a variable result to track the minimum length of subarray to be removed. Initially, this is set to right_index, which represents removing the entire segment from that point to the end of the array.
  • Initialize another pointer left_index at the start of the list. Iterate from the start to just before the right_index, ensuring that the elements from the very beginning are non-decreasing until left_index.
  • For each position of left_index, increment right_index until the element at right_index is not smaller than the element at left_index. This ensures that the elements after left_index up to right_index can form a non-decreasing sequence with the previous elements.
  • Update result to be the minimum of its current value or the difference between right_index and left_index minus one, which represents the length of the current removable subarray.
  • Continue this process until left_index surpasses or meets right_index.
  • Finally, return result, which gives the minimum length of the subarray that needs to be removed to make the original array sorted.

This solution ensures a methodical reduction of the problem using efficient pointers and comparisons, making it suitable for large arrays where brute-force methods would be computationally expensive.

Comments

No comments yet.