面试题16 部分排序

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

示例:

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

提示:

0 <= len(array) <= 1000000

解题思路

首先理解题意
[1,2,4,7,10,11,7,12,6,7,16,18,19]
默认数组升序,在有序数组中,找到一组最小的无序数组左右边界,将这组无序数组排序后,整体有序。

  1. 那么从左到右数值递增,当找到非递增的那个值它一定包含在我们需要的无序数组中,我们只需要从左到右遍历整体数组找到最后一个非递增的值并记录下标位置,它就是我们需要的无序数组的右边界。
  2. 同理数组从右往左递减,当找到非递减的那个值一定也包含在我们需要的无序数组中,我们只需要从右到左遍历整体数组找到最后一个非递减的值并记录下标位置,它就是我们需要的无序数组的左边界。
  3. 如果没有找到一定就是整体有序,则左右边界为-1,所以我们只需要初始化的时候定义就ok。

代码

class Solution {
    public int[] subSort(int[] array) {
        //右边界
        int left=0;
        //左边界
        int right=array.length-1;
        int max=-999;
        int min=10000;
        int i,j;
        //初始化
        i=-1;
        j=-1;
        //从左往右遍历 数组元素依次递增,所以每次都更新最大值,当后面的值比前一个值小的时候则无序,我们只需遍历找到最后一个能使数组无序的值它的下标就是右边界
        while(left<=array.length-1){
            if(array[left]>=max){
                max=array[left];
            }else{
                i=left;
            }
            left++;
        }
        //从右往左遍历 同理
        while(right>=0){
            if(array[right]<=min){
                min=array[right];
            }else{
                j=right;
            }
            right--;
        }
        return new int[]{j,i};
    }
}

复杂度

时间复杂度o(n)
空间复杂度o(1)

猜你喜欢

转载自blog.csdn.net/qq_35416214/article/details/106767852