给你一个整数数组 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
进阶:你可以设计一个时间复杂度为 O(n) 的解决方案吗?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shortest-unsorted-continuous-subarray
(1)排序
(2)单调栈
//思路1————排序
public int findUnsortedSubarray(int[] nums) {
int length = nums.length;
//深拷贝一个新的数组 newNums
int[] newNums = Arrays.copyOf(nums, length);
//对数组 newNums 进行排序
Arrays.sort(newNums);
int left = 0, right = length - 1;
//对比 nums 和 newNums,找出最短子数组的左右起点 left 和 right
while (left < length && nums[left] == newNums[left]) {
left++;
}
while (right >= 0 && nums[right] == newNums[right]) {
right--;
}
return right - left + 1 <= 0 ? 0 : right - left + 1;
}
//思路2————单调栈
public int findUnsortedSubarray(int[] nums) {
int length = nums.length;
int left = Integer.MAX_VALUE;
int right = Integer.MIN_VALUE;
//单调递增栈,存储元素索引
Stack<Integer> incrStack = new Stack<>();
for (int i = 0; i < length; i++) {
while (!incrStack.isEmpty() && nums[incrStack.peek()] > nums[i]) {
//栈中弹出的索引所对应的元素是乱序元素,其中最小的索引就是乱序子数组的左边界
left = Math.min(left, incrStack.pop());
}
incrStack.push(i);
}
//单调递减栈,存储元素索引
Stack<Integer> descStack = new Stack<>();
for (int i = length - 1; i >= 0; i--) {
while (!descStack.isEmpty() && nums[descStack.peek()] < nums[i]) {
//栈中弹出的索引所对应的元素是乱序元素,其中最大的索引就是乱序子数组的右边界
right = Math.max(right, descStack.pop());
}
descStack.push(i);
}
if (left == Integer.MAX_VALUE && right == Integer.MIN_VALUE) {
//单调栈没有弹出任何元素,即数组 nums 本来就是有序的
return 0;
} else {
return right - left + 1;
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_43004044/article/details/124996760
内容来源于网络,如有侵权,请联系作者删除!