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] Output: 0
Constraints:
1 <= nums.length <= 104
-105 <= nums[i] <= 105
Follow up: Can you solve it in
O(n)
time complexity?The problem asks to find the shortest continuous subarray within a given array nums
that, when sorted, would make the entire array sorted in non-decreasing order. The solution can be approached in two ways: sorting the entire array and comparing it to the original, or using a two-pointer approach that maintains maximum and minimum values during traversal.
This approach leverages the simplicity of sorting.
Sort a copy: Create a sorted copy of the input array nums
. This step uses a standard sorting algorithm, resulting in O(n log n) time complexity.
Find differing indices: Iterate through both the original and sorted arrays simultaneously. Identify the leftmost index (l
) where the original and sorted arrays differ, and the rightmost index (r
) where they differ.
Calculate subarray length: The length of the shortest unsorted continuous subarray is r - l + 1
. If l
and r
remain unchanged (no differences found), the array is already sorted, and the result is 0.
This approach is more efficient, achieving linear time complexity.
Initialize: Set l
and r
to -1. These will track the left and right boundaries of the unsorted subarray. Initialize mi
(minimum) to infinity and mx
(maximum) to negative infinity.
Left-to-right traversal: Iterate through the array from left to right.
x
is less than the current maximum mx
, it's out of order, so update r
to the current index.mx
to the current element.Right-to-left traversal: Iterate through the array from right to left.
mi
, it's out of order, so update l
to the current index.mi
to the current element.Return length: If r
remains -1, the array was already sorted. Otherwise, the length of the unsorted subarray is r - l + 1
.
Time Complexity Analysis:
Space Complexity Analysis:
Approach 1:
def findUnsortedSubarray(nums):
sorted_nums = sorted(nums)
l, r = 0, len(nums) - 1
while l <= r and nums[l] == sorted_nums[l]:
l += 1
while l <= r and nums[r] == sorted_nums[r]:
r -= 1
return r - l + 1
Approach 2:
import sys
def findUnsortedSubarray(nums):
mi, mx = sys.maxsize, -sys.maxsize
l, r = -1, -1
for i, x in enumerate(nums):
if mx > x:
r = i
else:
mx = x
if mi < nums[len(nums) - 1 - i]:
l = len(nums) - 1 - i
else:
mi = nums[len(nums) - 1 - i]
return 0 if r == -1 else r - l + 1
The second approach (two-pointer traversal) is generally preferred due to its better time complexity. The code examples in other languages (Java, C++, Go, TypeScript, Rust) would follow a very similar structure to these Python examples, reflecting the same algorithms.