1. 程式人生 > 其它 >LeetCode 1574 刪除最短的子陣列使得剩餘陣列有序(二分法、雙指標法)

LeetCode 1574 刪除最短的子陣列使得剩餘陣列有序(二分法、雙指標法)

技術標籤:leetcode二分法leetcode資料結構雙指標法C++

題目描述:
給你一個整數陣列 arr ,請你刪除一個子陣列(可以為空),使得 arr 中剩下的元素是 非遞減 的。

一個子陣列指的是原陣列中連續的一個子序列。

請你返回滿足題目要求的最短子陣列的長度。

思路:
方法一:二分法

方法二:雙指標

程式碼如下:
二分法:

class Solution {
public:
    bool check(vector<int>&nums,int n,int mid){
        if(mid==n-1) return true;
        int
left=0,right=n-1; while(left<right&&nums[left]<=nums[left+1]) left++; while(left<right&&nums[right-1]<=nums[right]) right--; if(right<=mid||n-left-1<=mid) return true; if(right-left-1>mid) return false; for(int i=max(0,right-
mid-1);i<=left&&i+mid+1<n;i++){ if(nums[i]<=nums[i+mid+1]) return true; } return false; } int findLengthOfShortestSubarray(vector<int>& arr) { int n=arr.size(); int left=0,right=n-1; while(left<right){ int
mid=left+(right-left)/2; if(check(arr,n,mid)){ right=mid; } else{ left=mid+1; } } return left; } };

雙指標法:

class Solution {
public:
    int findLengthOfShortestSubarray(vector<int>& arr) {
        if(arr.size()<2) return 0;
        int n=arr.size();
        int left=0,right=n-1;
        while(left<n-1&&arr[left]<=arr[left+1]){
            left++;
        }
        if(left==n-1) return 0;
        while(right>0&&arr[right]>=arr[right-1]){
            right--;
        }
        int res=min(right,(n-1)-(left+1)+1);
        int i=0;
        int j=right;
        while(i<=left&&j<=n-1){
            if(arr[i]<=arr[j]){
                res=min(res,j-i-1);
                i++;
            }
            else{
                j++;
            }
        }
        return res;
    }
};