Shortest Unsorted Continuous Subarray — Problem & Solution
Shortest Unsorted Continuous Subarray solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem.
Shortest Unsorted Continuous Subarray is a medium coding problem on arrays, sorting and two pointers, asked in Amazon, Google, Adobe and LiveRamp interviews.
- Difficulty: Medium
- Topics: Arrays, Sorting, Two Pointers, Monotonic Stack
- Asked at: Amazon, Google, Adobe, LiveRamp
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Given an integer array nums, find the shortest contiguous subarray such that sorting that subarray in ascending order leaves the whole array sorted in ascending order.
Return the length of that subarray. If the array is already sorted, return 0.
Example 1
Input: nums = [2,6,4,8,10,9,15]
Output: 5
Explanation: Sorting [6,4,8,10,9] sorts the whole array.
Example 2
Input: nums = [1,2,3,4]
Output: 0
Example 3
Input: nums = [1]
Output: 0
Constraints
1 <= nums.length <= 40-1000 <= nums[i] <= 1000
Follow-up: Can you do it in O(n) without sorting?
Hints for Shortest Unsorted Continuous Subarray
Hint 1
Compare the array with its sorted copy: the answer spans the first and last positions that differ.
Hint 2
For O(n), sweep right tracking the running maximum — the last index that falls below it is the right edge.
Hint 3
Sweep left tracking the running minimum to find the left edge the same way.
How to solve Shortest Unsorted Continuous Subarray
Compare the array with its sorted copy: everything outside the first and last mismatches is already in its final place.
Approach
- Sort a copy.
- Advance
leftwhilenums[left] == sorted[left]. - Retreat
rightwhilenums[right] == sorted[right]. - Return 0 if
leftran off the end, elseright - left + 1.
Why it works
Positions where the original already matches its sorted counterpart need not move, and the window between the outermost mismatches is the minimal region whose sort fixes the array.
Complexity
- Time —
O(n log n) - Space —
O(n)
Pitfalls
- The O(n) version sweeps right tracking the running max (the last index below it is the right edge) and left tracking the running min for the left edge.
- An already-sorted array must return 0, not 1.
Reference solution
Python
def findUnsortedSubarray(nums):
sorted_nums = sorted(nums)
left, right = 0, len(nums) - 1
while left < len(nums) and nums[left] == sorted_nums[left]:
left += 1
while right > left and nums[right] == sorted_nums[right]:
right -= 1
return 0 if left >= len(nums) else right - left + 1Java
public static int findUnsortedSubarray(int[] nums) {
int[] sorted = Arrays.copyOf(nums, nums.length);
Arrays.sort(sorted);
int left = 0, right = nums.length - 1;
while (left < nums.length && nums[left] == sorted[left]) left++;
while (right > left && nums[right] == sorted[right]) right--;
return left >= nums.length ? 0 : right - left + 1;
}C++
int findUnsortedSubarray(vector<int>& nums) {
vector<int> sorted = nums;
sort(sorted.begin(), sorted.end());
int n = (int) nums.size();
int left = 0, right = n - 1;
while (left < n && nums[left] == sorted[left]) left++;
while (right > left && nums[right] == sorted[right]) right--;
return left >= n ? 0 : right - left + 1;
}JavaScript
var findUnsortedSubarray = function(nums) {
const sorted = nums.slice().sort(function(a, b) { return a - b; });
let left = 0, right = nums.length - 1;
while (left < nums.length && nums[left] === sorted[left]) left++;
while (right > left && nums[right] === sorted[right]) right--;
return left >= nums.length ? 0 : right - left + 1;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 1199 arrays problems · the whole catalogue
Learn the technique: Arrays · Sorting Algorithms