Program to find shortest subarray to be removed to make array sorted in Python

Given an array, we need to find the shortest subarray to remove so that the remaining elements are in non-decreasing (sorted) order. This problem involves finding the longest possible sorted subsequence that can be formed by keeping elements from both ends of the array.

So, if the input is like arr = [10,20,30,100,40,20,30,50], then the output will be 3 because we can remove [100, 40, 20] which is the smallest subarray of length 3, and by removing these all remaining elements are in non-decreasing order [10,20,30,30,50].

Algorithm

To solve this, we will follow these steps:

  • Add sentinel values: 0 at the beginning and infinity at the end
  • Use two pointers to build sorted sequences from left and right ends
  • Find the maximum length of combined sorted sequences
  • Return original length minus maximum sorted length

Example

def solve(arr):
    n = len(arr)
    # Add sentinel values to handle edge cases
    arr = [0] + arr + [float("inf")]
    A, B = [], []  # A: left sorted, B: right sorted
    p, q = 1, len(arr) - 2  # Pointers for left and right
    M = 0  # Maximum length of sorted subsequence
    
    while p <= q:
        if arr[p-1] <= arr[p]:
            # Extend left sorted sequence
            A.append(arr[p])
            p += 1
        elif arr[q] <= arr[q+1]:
            # Extend right sorted sequence
            B.append(arr[q])
            # Remove elements from A that break sorting with B
            while A and A[-1] > B[-1]:
                A.pop()
            q -= 1
        else:
            # Can't extend either sequence
            break
        
        # Update maximum sorted length
        M = max(M, len(A) + len(B))
    
    return n - M

# Test the function
arr = [10, 20, 30, 100, 40, 20, 30, 50]
result = solve(arr)
print(f"Shortest subarray length to remove: {result}")
print(f"Original array: {arr}")
Shortest subarray length to remove: 3
Original array: [10, 20, 30, 100, 40, 20, 30, 50]

How It Works

The algorithm uses a two-pointer approach:

  • Left pointer (p): Builds the longest increasing sequence from the left
  • Right pointer (q): Builds the longest increasing sequence from the right
  • Compatibility check: Ensures elements from left sequence ? elements from right sequence
  • Result: Total length minus maximum sorted subsequence length

Step-by-Step Trace

For array [10,20,30,100,40,20,30,50]:

def solve_with_trace(arr):
    n = len(arr)
    arr = [0] + arr + [float("inf")]
    A, B = [], []
    p, q = 1, len(arr) - 2
    M = 0
    
    print(f"Modified array: {arr}")
    print(f"Initial: p={p}, q={q}")
    
    step = 1
    while p <= q:
        print(f"\nStep {step}:")
        if arr[p-1] <= arr[p]:
            A.append(arr[p])
            print(f"  Extended left: A={A}")
            p += 1
        elif arr[q] <= arr[q+1]:
            B.append(arr[q])
            print(f"  Extended right: B={B}")
            while A and A[-1] > B[-1]:
                removed = A.pop()
                print(f"  Removed {removed} from A: A={A}")
            q -= 1
        else:
            print("  Cannot extend either sequence, breaking")
            break
        
        M = max(M, len(A) + len(B))
        print(f"  A={A}, B={B}, M={M}")
        step += 1
    
    return n - M

# Trace the execution
arr = [10, 20, 30, 100, 40, 20, 30, 50]
result = solve_with_trace(arr)
print(f"\nFinal result: {result}")
Modified array: [0, 10, 20, 30, 100, 40, 20, 30, 50, inf]
Initial: p=1, q=8

Step 1:
  Extended left: A=[10]
  A=[10], B=[], M=1

Step 2:
  Extended left: A=[10, 20]
  A=[10, 20], B=[], M=2

Step 3:
  Extended left: A=[10, 20, 30]
  A=[10, 20, 30], B=[], M=3

Step 4:
  Extended left: A=[10, 20, 30, 100]
  A=[10, 20, 30, 100], B=[], M=4

Step 5:
  Extended right: B=[50]
  Removed 100 from A: A=[10, 20, 30]
  A=[10, 20, 30], B=[50], M=4

Step 6:
  Extended right: B=[50, 30]
  A=[10, 20, 30], B=[50, 30], M=5

Final result: 3

Conclusion

This algorithm efficiently finds the shortest subarray to remove by building sorted sequences from both ends and ensuring compatibility between them. The time complexity is O(n) and space complexity is O(n) for the auxiliary arrays.

Updated on: 2026-03-26T13:46:31+05:30

344 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements