LeetCode每日一题(1574. Shortest Subarray to be Removed to Make Array Sorted)

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

Return the length of the shortest subarray to remove.

A subarray is a contiguous subsequence of the array.

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.

Constraints:

  • 1 <= arr.length <= 105
  • 0 <= arr[i] <= 109

  1. 找以 arr[0]为开头的连续非递减数组的结尾 index, i
  2. 找以 arr[arr.len()-1]为结尾的连续非递减数组的开头 index, j
  3. 用 arr[…i]与 arr[j…]这两个数组来拼合出一个非递减数组

假设 dp[i][j]是用 arr[…i]与 arr[j…]删掉某些元素之后拼合成非递减数组所需要删除的最少元素数量, 那 dp[i][j] = min(dp[i-1][j], dp[i][j+1])。 注意考虑只用 arr[…i]或者只用 arr[j…]的情况, 因为这两个本身就是非递减的数组。


use std::collections::HashMap;

impl Solution {
    fn dp(arr: &Vec<i32>, i: usize, j: usize, cache: &mut HashMap<(usize, usize), i32>) -> i32 {
        if arr[i] <= arr[j] {
            return (j - i - 1) as i32;
        }
        if i == 0 && j == arr.len() - 1 {
            return arr.len() as i32 - 1;
        }
        if i == 0 {
            let ans = if let Some(c) = cache.get(&(i, j + 1)) {
                *c
            } else {
                Solution::dp(arr, i, j + 1, cache)
            };
            cache.insert((i, j), ans);
            return ans;
        }
        if j == arr.len() - 1 {
            let ans = if let Some(c) = cache.get(&(i - 1, j)) {
                *c
            } else {
                Solution::dp(arr, i - 1, j, cache)
            };
            cache.insert((i, j), ans);
            return ans;
        }
        let inc_j = if let Some(c) = cache.get(&(i, j + 1)) {
            *c
        } else {
            Solution::dp(arr, i, j + 1, cache)
        };
        let dsc_i = if let Some(c) = cache.get(&(i - 1, j)) {
            *c
        } else {
            Solution::dp(arr, i - 1, j, cache)
        };
        cache.insert((i, j), inc_j.min(dsc_i));
        inc_j.min(dsc_i)
    }
    pub fn find_length_of_shortest_subarray(arr: Vec<i32>) -> i32 {
        let left_endpoint = arr.windows(2).position(|l| l[0] > l[1]);
        if left_endpoint.is_none() {
            return 0;
        }
        let i = left_endpoint.unwrap();
        let j = arr.len() - arr.windows(2).rev().position(|l| l[0] > l[1]).unwrap() - 1;
        let only_left = arr.len() as i32 - (i as i32 + 1);
        let only_right = arr.len() as i32 - (arr.len() as i32 - j as i32);
        let mut ans = only_left.min(only_right);
        ans = ans.min(Solution::dp(&arr, i, j, &mut HashMap::new()));
        ans
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值