【LeetCode】Day189-区间子数组个数

题目

795. 区间子数组个数【中等】

题解

注意题目中说的是 子数组的最大值在 [left,right] 区间就行,翻译一下就是子数组中不能有超过right的元素,且至少有一个元素在 [left,right] 区间内

一次遍历

维护两个变量
last1:目标区间元素最后一次出现的位置
last2:非目标区间元素最后一次出现的位置
如果last1存在,则结果+=last1-last2

class Solution {
    public int numSubarrayBoundedMax(int[] nums, int left, int right) {
        int n=nums.length,res=0,last1=-1,last2=-1;
        for(int i=0;i<n;i++){
            if(nums[i]>=left&&nums[i]<=right)
                last1=i;//目标区间元素最后一次出现的位置
            else if(nums[i]>right){
                last2=i;//非目标区间元素最后一次出现的位置
                last1=-1;//标记此轮跳过res更新
            }
            if(last1!=-1)
                res+=last1-last2;
        }
        return res;
    }
}

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( 1 ) O(1) O(1)

计数

[…,right]-[…,left-1],两个区间元素个数相减,得到[left,right]区间的元素个数

class Solution {
    public int numSubarrayBoundedMax(int[] nums, int left, int right) {
        return count(nums,right)-count(nums,left-1);
    }
    public int count(int[] nums,int lower){
        int cur=0,res=0;
        for(int x:nums){
            cur=x<=lower?cur+1:0;//i左侧有多少个连续的元素<=lower
            res+=cur;
        }
        return res;
    }
}

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( 1 ) O(1) O(1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值