[leetcode] 1574. Shortest Subarray to be Removed to Make Array Sorted

Description

Given an integer array arr, remove a subarray (can be empty) from arr such that the remaining elements in arr are non-decreasing.

A subarray is a contiguous subsequence of the array.

Return the length of the shortest subarray to remove.

Example 1:

Input: arr = [1,2,3,10,4,2,3,5]
Output: 3
Explanation: The shortest subarray we can remove is [10,4,2] of length 3. The remaining elements after that will be [1,2,3,3,5] which are sorted.
Another correct solution is to remove the subarray [3,10,4].

Example 2:

Input: arr = [5,4,3,2,1]
Output: 4
Explanation: Since the array is strictly decreasing, we can only keep a single element. Therefore we need to remove a subarray of length 4, either [5,4,3,2] or [4,3,2,1].

Example 3:

Input: arr = [1,2,3]
Output: 0
Explanation: The array is already non-decreasing. We do not need to remove any elements.

Example 4:

Input: arr = [1]
Output: 0

Constraints:

  • 1 <= arr.length <= 10^5
  • 0 <= arr[i] <= 10^9

分析

题目的意思是:给你一个数组,要求移除一个子数组,然后剩下的数构成一个非递减数列,求移除的最小长度。这里可以把问题转换为保留数组的最大长度,找出最大长度就可以求出移除的最小长度了。

首先,移除的子数组必须是连续的,所以就只能移除中间的部分,有三种情况,包含开头,包含结尾,开头和结尾都包含。所以就分三种情况来写代码了,首先遍历求出开头最大长度非递减数列,然后求出尾部最大长度非递减数列,然后再遍历求中间的就行了。

代码

class Solution:
    def findLengthOfShortestSubarray(self, arr: List[int]) -> int:
        n=len(arr)
        left_idx=0
        right_idx=n-1
        for i in range(n-1):
            if(arr[i]<=arr[i+1]):
                left_idx=i+1
            else:
                break
        if(left_idx==n-1):
            return 0
        for i in range(n-1,left_idx,-1):
            if(arr[i-1]<=arr[i]):
                right_idx=i-1
            else:
                break
        res=max(left_idx+1,n-right_idx)
        i=0
        j=right_idx
        while(i<=left_idx and j<n):
            if(arr[i]<=arr[j]):
                res=max(res,i+1+n-j)
                i+=1
            else:
                j+=1
        return n-res

参考文献

[LeetCode] Detailed Explanation with Code O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值