b_lc_删除最短的子数组使剩余数组有序(分类讨论+双指针)
给你一个整数数组 arr ,请你删除一个子数组(可以为空),使得 arr 中剩下的元素是 非递减 的。
一个子数组指的是原数组中连续的一个子序列。
请你返回满足题目要求的最短子数组的长度。
输入:arr = [1,2,3,10,4,2,3,5]
输出:3
解释:我们需要删除的最短子数组是 [10,4,2] ,长度为 3 。剩余元素形成非递减数组 [1,2,3,3,5] 。
另一个正确的解为删除子数组 [3,10,4] 。
提示:
1 <= arr.length <= 10^5
0 <= arr[i] <= 10^9
方法一:分类讨论+双指针
- 方案一:删除完全左边的降序序列,记为 [0, l]
- 方案二:删除完全右边的降序序列,记为 [r,n)
- 方案三:经过上面的筛选,此时区间[0,l]和[r,n)都为非降序序列,此时考虑删除中间一段[i+1, j-1]
class Solution {
public:
int findLengthOfShortestSubarray(vector<int>& A) {
int n=A.size(), l=1,r=n-1, ans=n+1;
while (l<n && A[l-1]<=A[l]) l++;
if (l==n) return 0;
while (r>0 && A[r-1]<=A[r]) r--;
ans=min(n-l, r);
int i=0, j=r;
while (i<l && j<n) {
if (A[i]<=A[j]) {
ans=min(ans, j-i-1), i++;
} else { //由于A[i]>A[j],A[l..r]都是降序,所以A[j]必须要删
j++;
}
}
return ans;
}
};
复杂度分析
- Time:\(O(n)\),
- Space:\(O(1)\)