581. 最短无序连续子数组

166 阅读1分钟

给你一个整数数组 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

题解:

/**
 * @param {number[]} nums
 * @return {number}
 */
// 方法一:排序对比
var findUnsortedSubarray = function (nums) {
    const sortNums = [...nums].sort((a, b) => a - b)
    let left = 0, right = nums.length - 1;
    // 从左侧对比 当是递增有序时   left < nums.length为边界情况
    while (nums[left] == sortNums[left] && left < nums.length) {
        left++
    }
    // 从右侧对比 当时递减有序时 right为边界情况
    while (nums[right] == sortNums[right] && right) {
        right--
    }
    // 判断right - left + 1 >时有最短子数组
    return right - left + 1 > 0 ? right - left + 1 : 0;
};

// 方法二:单调栈
var findUnsortedSubarray = function (nums) {
    const stack = [];
    // left 和 right 为下标初始值
    let len = nums.length, left = len, right = 0
    // 单调递增 当前元素小于栈顶元素时,出栈, 获取当前元素下标
    // 当前下标为非递增第一个元素下标
    for (let i = 0; i < len; i++) {
        while (stack.length && nums[i] < nums[stack[stack.length - 1]]) {
            left = Math.min(left, stack.pop())
        }
        stack.push(i)
    }
    stack.length = 0;
    // 单调递减 当前元素大于栈顶元素时,出栈,获取当前元素下标
    // 当前下标为非递减第一个元素下标
    for (let i = len - 1; i >= 0; i--) {
        while (stack.length && nums[i] > nums[stack[stack.length - 1]]) {
            right = Math.max(right, stack.pop())
        }
        stack.push(i)
    }
    return right - left + 1 > 0 ? right - left + 1 : 0;
};

来源:力扣(LeetCode)

链接:leetcode.cn/problems/sh…

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。