这是我参与8月更文挑战的第N天,活动详情查看:8月更文挑战
581. 最短无序连续子数组
给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
请你找出符合题意的 最短 子数组,并输出它的长度。
示例 1:
输入:nums = [2,6,4,8,10,9,15] 输出:5 解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。 示例 2:
输入:nums = [1,2,3,4] 输出:0 示例 3:
输入:nums = [1] 输出:0
解题思路
因为其中一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
说明只有中间这个子数组是乱序的,前面一部分和后面一部分都是递增的。
-
[0, l-1],这个部分是数组的前部分,这个部分是已经排序好的结果,说明这个部分最大数就在l-1,并且这个部分所有的数都是小于后面两个部分的所有数
-
[l, r],这个部分就是我们要求的子数组,这部分是已经乱序的
-
[r+1, n-1],这个部分是数组的后部分,这个部分同样也是排序好的结果,其中最小的数下标为r+1,并且这个部分全部的数都要大于前面两个部分的数
因此我们可以维护一个从左到右的最大值和一个从右到左的最小值,最大值在前面和后面的递增数组中,都是正常递增的,但是在中间的乱序数组中,大值就会出现在小值的左边,当出现这种情况时,就说明了当前元素是在乱序数组当中的,对于最小值也是同样的道理
代码
class Solution {
public int findUnsortedSubarray(int[] nums) {
int min=Integer.MAX_VALUE,max=Integer.MIN_VALUE;
int n=nums.length; int l=-1,r=-1;
for (int i=0;i<n;i++)
{
if (max>nums[i])
{
r=i;
}else {
max=nums[i];
}
if (min<nums[n-i-1])
{
l=n-i-1;
}else {
min=nums[n-i-1];
}
}
return r==-1?0:r-l+1;
}
}