LeetCode 2970 | 统计移除递增子数组的数目

题目
如果 nums 的一个子数组满足:移除这个子数组后剩余元素严格递增,那么我们称这个子数组为移除递增子数组。比方说,[5, 3, 4, 6, 7] 中的 [3, 4] 是一个移除递增子数组,因为移除该子数组后,[5, 3, 4, 6, 7] 变为 [5, 6, 7] ,是严格递增的。
请你返回 nums 中 移除递增 子数组的总数目。
注意 ,剩余元素为空的数组也视为是递增的。

示例 1:

输入:nums = [1,2,3,4]
输出:10
解释:10 个移除递增子数组分别为:[1], [2], [3], [4], [1,2], [2,3], [3,4], [1,2,3], [2,3,4] 和 [1,2,3,4]。移除任意一个子数组后,剩余元素都是递增的。注意,空数组不是移除递增子数组。

💡1. 可以注意到,需要移除的是一个在nums里连续的子数组,所以我们可以用双指针L、R枚举子数组的两端。
💡2. 如果[0, L]是严格递增的,则移除递增子数组为[L + 1, R];那么[0, L - 1]也是严格递增的,[L, R]也是移除递增子数组。

✨对于R = n时
我们可以找到最大的L,使得[0, L]严格递增,那么[L + 1, R]为移除递增子数组,子数组的左端点可以从 0->L,总计 L + 1 个子数组。如果L < R,那么[L + 1, R]也存在,需要子数组加一。
✨子数组的右端点R继续右移(n - 1) -> 0
此时,需要子数组的左右两端合并能组成一个严格递增数组。
左边的数字我们在前面得到L的时候已经判断过严格递增了,我们还需要判断右边的数字是严格递增的,在R每改变一次的时候判断一次当前数字是否比后一个低。
if(nums[r] >= nums[r + 1]) break;
同时还需要判断左右两边的数组能否合并:如果nums[L]比nums[R]大的话,我们需要将L指针左移,直到nums[L]小于nums[R]。
while(l >= 0 && nums[l] >= nums[r]) l--;

💟代码

int incremovableSubarrayCount(vector<int>& nums) {
        int ans = 0, n = nums.size(), l = 0, r = n - 1;
        while(l < n - 1 && nums[l] < nums[l + 1]) l++;
        ans += l + 1;
        if(l < r) ans++;
        while(l >= 0 && nums[l] >= nums[r]) l--;
        ans += l + 1;
        if(l < r - 1) ans++;
        for(r = n - 2; r >= 0; r--){
            if(nums[r] >= nums[r + 1]) break;
            while(l >= 0 && nums[l] >= nums[r]) l--;
            ans += l + 1;
            if(l < r - 1) ans++;
        }
        return ans;
    }
posted @ 2026-03-14 19:40  hhhueu  阅读(2)  评论(0)    收藏  举报