LeetCode 1574 刪除最短的子陣列使得剩餘陣列有序(二分法、雙指標法)
阿新 • • 發佈:2021-01-16
技術標籤: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;
}
};