6207. 统计定界子数组的数目「多指针」

第315场周赛hard题,没有想出来,在此做记录,参考了三位大佬的题解:

  1. 灵佬的题解
  2. twilight的题解
  3. newhar的题解

思路

本题思路相当于把一个连续的数组分为若干个块,每个块外为[minK, maxk]范围外的数字,块内为范围内的数字,且包含有minKmaxK。以下图为例:
minK = 2maxK = 4

遍历nums,记录每个块中最后出现的maxK以及minK出现的位置下标lastMax以及lastMin
在每一个块内部,假设其起始坐标为0,且块内下标lastMax以及lastMin已经得到,则遇到下一个[minK, maxK]范围内的数时,以这个数下标为右边界,左边界可在[0, min(lastMax, lastMin)]中任意取得。即可得ans += min(lastMax, lastMin)

在遍历的时候,每个块的起始坐标不为0,可以额外维护一个变量outI,表示最后一个范围外的数的下标。若min(lastMax, lastMin) < outI,说明outI右侧maxKminK还没有全部出现,因此此时当前答案加0。

代码如下:

class Solution {
public:
    long long countSubarrays(vector<int>& nums, int minK, int maxK) {
        int lastMin = -1, lastMax = -1, outI = -1;
        long long ans = 0;
        
        for(int i=0; i< nums.size(); ++i){
            //枚举右边界
            if(nums[i] == minK){
                lastMin = i;
            }
            if(nums[i] == maxK){
                lastMax = i;
            }
            if(nums[i] < minK || nums[i] > maxK){
                outI = i;
            }
            ans += max(min(lastMin, lastMax) - outI, 0);
        }
        
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值