Leetcode面试题 16.16.部分排序【暴力|线性】

问题描述

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

解题报告

暴力求解

最暴力的解法是:

  • 寻找左边界时
    从左至右遍历数组中的每个元素,然后查找其后是否有比它更小的元素,如果有,左边界确定好;
  • 寻找有边界时:
    同理,从右至左遍历数组中的每个元素,然后查找其前是否有比它更大的元素,如果有,左边界确定好。

线性求解

  • 寻找右边界时:
    从左到右进行遍历,同时记录左边的最大值,一旦发现当前元素比左边最大值更小,说明该元素需要参与重新排序,即更新右边界。
  • 寻找左边界时:
    从右至左进行遍历,同时记录右边的最小值,一旦发现当前元素比右边最小值更大时,说明该元素需要参与重新排序,即更新左边界。

实现代码

暴力求解

class Solution {
public:
    vector<int> subSort(vector<int>& array) {
        int n=array.size(),l=-1,r=-1;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                if(array[j]<array[i]){
                    l=i;
                    break;
                }
            }
            if(l!=-1){
                break;
            }
        }
        for(int i=n-1;i>=0;i--){
            for(int j=i-1;j>=0;j--){
                if(array[j]>array[i]){
                    r=i;
                    break;
                }
            }
            if(r!=-1){
                break;
            }
        }
        return {l,r};
    }
};

线性求解

class Solution{
    public:
        vector<int> subSort(vector<int>&nums){
            int n=nums.size(),MAXX=INT_MIN,MINN=INT_MAX,l=-1,r=-1;
            for(int i=0;i<n;i++){
                if(nums[i]>=MAXX) MAXX=nums[i];
                else r=i;
            }
            for(int j=n-1;j>=0;j--){
                if(nums[j]<=MINN) MINN=nums[j];
                else l=j;
            }
            return {l,r};
        }
};

参考资料

[1] Leetcode 面试题 16.16.部分排序
[2] 【每日算法Day 88】超越妹妹教你如何做这道排序题

MD_
发布了139 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_27690765/article/details/105305463