Given an integer array nums, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order.
Return the shortest such subarray and output its length.
OR
Give a list of unsorted number, find the min window or min sublist or min subarray of the input, such as if sublist is sorted, the whole list is sorted too.
Instead of returning right - left + 1, return (left, right) where left and right are the start and end indices of the unsorted window. If the array is already sorted, return (-1, -1) or null to indicate no sorting is needed.
Examples for Variant 1:
1
2
3
Input: nums =[2,6,4,8,10,9,15]Output: (1,5)Explanation: Need to sort subarray from index 1 to 5:[6,4,8,10,9]
1
2
3
Input: nums =[1,2,3,4]Output: (-1,-1)Explanation: Array is already sorted
If we sort the array, the sorted version will show us which elements are out of place. By comparing the original and sorted arrays, we can find the boundaries of the shortest subarray that needs sorting.
classSolution {
publicintfindUnsortedSubarray(int[] nums) {
int n = nums.length;
int[] sortedNums = Arrays.copyOf(nums, n);
Arrays.sort(sortedNums);
int start = 0;
while (start < n && nums[start]== sortedNums[start]) start++;
int end = n - 1;
while (end > start && nums[end]== sortedNums[end]) end--;
return end - start + 1;
}
}
1
2
3
4
5
6
7
8
9
classSolution:
deffindUnsortedSubarray(self, nums):
sorted_nums = sorted(nums)
start, end =0, len(nums) -1while start < len(nums) and nums[start] == sorted_nums[start]:
start +=1while end > start and nums[end] == sorted_nums[end]:
end -=1return end - start +1
Instead of sorting, we can scan from both ends to find the boundaries of the unsorted subarray. By tracking the maximum and minimum values while traversing, we can identify where the order breaks and thus the minimal window to sort.
classSolution {
public:int findUnsortedSubarray(vector<int>& nums) {
int n = nums.size();
int left = n -1, right =0;
int max_num = nums[0], min_num = nums[n -1];
for (int i =0; i < n; ++i) {
max_num = max(max_num, nums[i]);
if (nums[i] < max_num) right = i;
}
for (int i = n -1; i >=0; --i) {
min_num = min(min_num, nums[i]);
if (nums[i] > min_num) left = i;
}
if (right <= left) return0;
return right - left +1;
}
};
funcfindUnsortedSubarray(nums []int) int {
n:= len(nums)
left, right:=n-1, 0maxNum, minNum:=nums[0], nums[n-1]
fori:=0; i < n; i++ {
ifnums[i] < maxNum {
right = i }
ifnums[i] > maxNum {
maxNum = nums[i]
}
}
fori:=n-1; i>=0; i-- {
ifnums[i] > minNum {
left = i }
ifnums[i] < minNum {
minNum = nums[i]
}
}
ifright<=left {
return0 }
returnright-left+1}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
publicintfindUnsortedSubarray(int[] nums) {
int n = nums.length;
int left = n - 1, right = 0;
int max = nums[0], min = nums[n - 1];
for (int i = 0; i < n; ++i) {
max = Math.max(max, nums[i]);
if (nums[i]< max) right = i;
}
for (int i = n - 1; i >= 0; --i) {
min = Math.min(min, nums[i]);
if (nums[i]> min) left = i;
}
if (right <= left) return 0;
return right - left + 1;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
funfindUnsortedSubarray(nums: IntArray): Int {
val n = nums.size
var left = n - 1var right = 0var maxNum = nums[0]
var minNum = nums[n - 1]
for (i in0 until n) {
maxNum = maxOf(maxNum, nums[i])
if (nums[i] < maxNum) right = i
}
for (i in n - 1 downTo 0) {
minNum = minOf(minNum, nums[i])
if (nums[i] > minNum) left = i
}
if (right <= left) return0return right - left + 1 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution:
deffindUnsortedSubarray(self, nums):
n = len(nums)
left, right = n -1, 0 max_num, min_num = nums[0], nums[-1]
for i in range(n):
max_num = max(max_num, nums[i])
if nums[i] < max_num:
right = i
for i in range(n -1, -1, -1):
min_num = min(min_num, nums[i])
if nums[i] > min_num:
left = i
if right <= left:
return0return right - left +1
impl Solution {
pubfnfind_unsorted_subarray(nums: Vec<i32>) -> i32 {
let n = nums.len();
letmut left = n -1;
letmut right =0;
letmut max_num = nums[0];
letmut min_num = nums[n -1];
for i in0..n {
max_num = max_num.max(nums[i]);
if nums[i] < max_num {
right = i;
}
}
for i in (0..n).rev() {
min_num = min_num.min(nums[i]);
if nums[i] > min_num {
left = i;
}
}
if right <= left {
return0;
}
(right - left +1) asi32 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
findUnsortedSubarray(nums: number[]):number {
constn=nums.length;
letleft=n-1, right=0;
letmaxNum=nums[0], minNum=nums[n-1];
for (leti=0; i<n; i++) {
maxNum= Math.max(maxNum, nums[i]);
if (nums[i] <maxNum) right=i;
}
for (leti=n-1; i>=0; i--) {
minNum= Math.min(minNum, nums[i]);
if (nums[i] >minNum) left=i;
}
if (right<=left) return0;
returnright-left+1;
}
}
Same as the main problem - we find the boundaries of the unsorted subarray by tracking maximum from left and minimum from right. The only difference is we return the actual indices instead of the length.
classSolution {
public: pair<int, int> findUnsortedSubarrayBounds(vector<int>& nums) {
int n = nums.size();
int left = n -1, right =0;
int max_num = nums[0], min_num = nums[n -1];
for (int i =0; i < n; ++i) {
max_num = max(max_num, nums[i]);
if (nums[i] < max_num) right = i;
}
for (int i = n -1; i >=0; --i) {
min_num = min(min_num, nums[i]);
if (nums[i] > min_num) left = i;
}
if (right <= left) return {-1, -1};
return {left, right};
}
};
classSolution {
publicint[]findUnsortedSubarrayBounds(int[] nums) {
int n = nums.length;
int left = n - 1, right = 0;
int max = nums[0], min = nums[n - 1];
for (int i = 0; i < n; ++i) {
max = Math.max(max, nums[i]);
if (nums[i]< max) right = i;
}
for (int i = n - 1; i >= 0; --i) {
min = Math.min(min, nums[i]);
if (nums[i]> min) left = i;
}
if (right <= left) returnnewint[]{-1, -1};
returnnewint[]{left, right};
}
}
classSolution {
funfindUnsortedSubarrayBounds(nums: IntArray): IntArray {
val n = nums.size
var left = n - 1var right = 0var maxNum = nums[0]
var minNum = nums[n - 1]
for (i in0 until n) {
maxNum = maxOf(maxNum, nums[i])
if (nums[i] < maxNum) right = i
}
for (i in n - 1 downTo 0) {
minNum = minOf(minNum, nums[i])
if (nums[i] > minNum) left = i
}
if (right <= left) return intArrayOf(-1, -1)
return intArrayOf(left, right)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution:
deffindUnsortedSubarrayBounds(self, nums: List[int]) -> Tuple[int, int]:
n = len(nums)
left, right = n -1, 0 max_num, min_num = nums[0], nums[-1]
for i in range(n):
max_num = max(max_num, nums[i])
if nums[i] < max_num:
right = i
for i in range(n -1, -1, -1):
min_num = min(min_num, nums[i])
if nums[i] > min_num:
left = i
if right <= left:
return (-1, -1)
return (left, right)
impl Solution {
pubfnfind_unsorted_subarray_bounds(nums: Vec<i32>) -> Vec<i32> {
let n = nums.len();
letmut left = n -1;
letmut right =0;
letmut max_num = nums[0];
letmut min_num = nums[n -1];
for i in0..n {
max_num = max_num.max(nums[i]);
if nums[i] < max_num {
right = i;
}
}
for i in (0..n).rev() {
min_num = min_num.min(nums[i]);
if nums[i] > min_num {
left = i;
}
}
if right <= left {
returnvec![-1, -1];
}
vec![left asi32, right asi32]
}
}