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)\)
posted @ 2020-09-06 21:06  童年の波鞋  阅读(279)  评论(0编辑  收藏  举报