题目
给你一个整数数组 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
提示
1 <= nums.length <= 104-105 <= nums[i] <= 105
解题思路
-
按照题目的提示,我们需要找到一个连续的子数组,对该子数组进行排序使得整个数组都是升序排列的,那么这里可以得到四种情况:
- [0,1,···,子数组]
- [0,1,···,子数组,···,n - 1, n]
- [子数组,···, n - 1, n]
- [子数组]
-
不管是那种情况,我们都只需要对一个子数组进行排序即可,其余不在子数组范围内的元素均已排好序,可以不用关注,那这里我们可以通过双指针来确定出子数组的左右边界,即可得到结果:
- 从左边开始找到最后一位比前面元素小的元素
- 从右边开始找到最后一位比后面元素大的元素
代码实现
class Solution {
public int findUnsortedSubarray(int[] nums) {
int n = nums.length;
// 定义左右边界两个指针,以及两个做判断使用的变量
int max = Integer.MIN_VALUE, left = -1, min = Integer.MAX_VALUE, right = n;
// 双向遍历数组,这里是 i 跟 j 分别遍历了一遍
for(int i = 0, j = n - 1; i < n; ++i, --j){
// 当前元素小于等于前面的元素,更新左边界指针的位置
if(max > nums[i]){
left = i;
}else{
max = nums[i];
}
// 当前元素大于后面的元素,更新右边界指针的位置
if(min < nums[j]){
right = j;
}else{
min = nums[j];
}
}
// 如果left指针没有移动,表示该数组为顺序数组,返回结果 0。
// 否则,返回子数组区间长度
return left == -1 ? 0 : left - right + 1;
}
}
复杂度分析
时间复杂度:O(n),两个指针都只分别遍历了一遍。
时间复杂度:O(1),常量级。
最后
文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!
如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!