[路飞]_leetcode-面试题 16.16-部分排序

题目描述

[题目地址]

给定一个整数数组,编写一个函数,找出索引mn,只要将索引区间[m,n]的元素排好序,整个数组就是有序的。注意:n-m尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n],若不存在这样的mn(例如整个数组是有序的),请返回[-1,-1]

示例:

输入: [1,2,4,7,10,11,7,12,6,7,16,18,19]
输出: [3,9]
复制代码

提示:

  • 0 <= len(array) <= 1000000

解题思路

我们可以首先从左往右找右边界,记录已处理区间中的最大值,如果在后续遍历过程中找到一个值比最大值小,说明此时出现了前大后小的情况,说明该位置是需要排序的,更新 n 等于当前下标,这样一次扫描后就确定了右边界 n。 同理可以从右往左找左边界,初始化 m = len-1len 为输入数组长度),记录已处理区间中的最小值, 如果找到一个值比最小值大,说明此时出现了前大后小的情况,说明该位置是需要排序的,则更新左边界 m 为该下标,这样一次扫描就确定了左边界 m
如此我们通过两次遍历数组就确定了 mn,最后判断 [m,n] 是否合法,如果合法,返回 [m,n],否则返回 [-1,-1

动画演示

leetcode-面试题 16.16-部分排序.gif

代码实现

var subSort = function(array) {
    let r = -1, l = -1; //两个指针记录一个升序,一个降序
    // 从左往右找最右边的区间值
    let max = Number.MIN_SAFE_INTEGER;
    // 第一次排序从小到大
    for(let i = 0; i < array.length; i++){
        if(array[i] >= max){
            max = array[i];
        }else{
            r = i;
        }
    }
    // 从右往左找,找最左边的区间值
    let min = Number.MAX_SAFE_INTEGER;
    for(let i = array.length - 1; i >= 0; i--){
        if(array[i] <= min){
            min = array[i];
        }else{
            l = i;
        }
    }
    return [l , r];
};
复制代码

至此我们就完成了leetcode-面试题 16.16-部分排序

猜你喜欢

转载自juejin.im/post/7061523106694692901