Shortest Unsorted Continuous Subarray - Complete Solution Guide
Shortest Unsorted Continuous Subarray is LeetCode problem 581, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Given an integer array nums , you need to find one continuous subarray such that if you only sort this subarray in non-decreasing order, then the whole array will be sorted in non-decreasing order. Return the shortest such subarray and output its length . Example 1: Input: nums = [2,6,4,8,10,9,15] Output: 5 Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order. Example 2: Input: nums = [1,2,3,4] Output: 0 Example 3: Input: nums = [1]
Detailed Explanation
The problem asks us to find the shortest continuous subarray within a given integer array `nums`, such that if we sort only that subarray in non-decreasing order, the entire array `nums` becomes sorted in non-decreasing order. The function should return the length of this shortest subarray. If the input array is already sorted, the function should return 0. The constraints limit the array size to a maximum of 10,000 elements, and each element's value ranges from -100,000 to 100,000.
Solution Approach
The solution employs a two-pass approach to find the `start` and `end` indices of the shortest unsorted subarray. The first pass iterates from left to right, maintaining a running maximum value. If an element is encountered that is less than the maximum value seen so far, the index of that element becomes a candidate for the right boundary (`end`). The second pass iterates from right to left, maintaining a running minimum value. If an element is encountered that is greater than the minimum value seen so far, the index of that element becomes a candidate for the left boundary (`start`). After both passes, the length of the unsorted subarray is calculated as `end - start + 1`. If no unsorted subarray is found (i.e., the array is already sorted), `end` will remain -1, and the function will return 0.
Step-by-Step Algorithm
- Step 1: Initialize `start` to 0 and `end` to -1. Initialize `max_val` to `nums[0]` and `min_val` to `nums[n-1]`.
- Step 2: Iterate from `i = 1` to `n-1`. In each iteration, if `nums[i] < max_val`, update `end` to `i`. Update `max_val` to `max(max_val, nums[i])`.
- Step 3: If `end` is still -1, it means the array is already sorted, so return 0.
- Step 4: Iterate from `i = n-2` to `0`. In each iteration, if `nums[i] > min_val`, update `start` to `i`. Update `min_val` to `min(min_val, nums[i])`.
- Step 5: Return `end - start + 1`.
Key Insights
- Insight 1: The unsorted subarray is defined by a left boundary `start` and a right boundary `end`. Elements outside this subarray are already in the correct sorted order.
- Insight 2: We can identify the right boundary `end` by iterating from the left and keeping track of the maximum value seen so far. If we encounter an element smaller than the current maximum, it violates the non-decreasing order and indicates the end of the potential unsorted subarray.
- Insight 3: Similarly, we can identify the left boundary `start` by iterating from the right and keeping track of the minimum value seen so far. If we encounter an element larger than the current minimum, it violates the non-decreasing order and indicates the start of the potential unsorted subarray.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Array, Two Pointers, Stack, Greedy, Sorting, Monotonic Stack.
Companies
Asked at: LiveRamp.