leetcode 0795 区间子数组个数 python 题解


一、题目

题目:给你一个整数数组 nums 和两个整数:left 及 right 。找出 nums 中连续、非空且其中最大元素在范围 [left, right] 内的子数组,并返回满足条件的子数组的个数。

二、思路

1、单调栈

本题给定了区间【left,right】,首先可以想到依次遍历,找到每个在区间内的数,看他们可以构成的子数组有哪些。
进而可以想到,看以该数为右端点的数组,有多少满足条件的子数组。(其实这也是一种解法)
想到此处,我们可以想到,如果该数在区间【left,right】内,以该数为子数组的最大数一定满足条件。单调栈可以快速找到第一个比该数大(小)的数,找到每个数左右第一个比其大的数记其位置为l,r
①如果该数在区间【left,right】中,(r-i) *(i-l) 为以该数为子数组最大数组满足题目要求的数量
②否则以该数为最大数的子数组一定不满足条件

过程:
先自左至右找到每个数右边第一个大于自身的数的坐标,存在数组R中。
再自右至左找到每个数左边第一个大于自身的数的坐标,存在数组L中。
最后遍历数组,如果在区间内,就统计以该数为最大数的子数组的个数。

TIPS:
为了防止重复,可将一个< 改为 <=

示例图

自左至右找到每个数右边第一个大于自身的数的坐标,存在数组R中。

在这里插入图片描述

自右至左找到每个数左边第一个大于自身的数的坐标,存在数组L中。

在这里插入图片描述
遍历数组,如果在区间内,就统计以该数为最大数的子数组的个数。
在这里插入图片描述

二、代码

python

代码如下:

class Solution:
    def numSubarrayBoundedMax(self, nums, left: int, right: int) -> int:
        n = len(nums)
        l,r = [-1]*n,[n]*n
        stack = []
        res = 0
        for i in range(n):
            while stack and nums[stack[-1]] < nums[i]:
                r[stack.pop()] = i
            stack.append(i)
        stack = []
        for j in range(n-1,-1,-1):
            while stack and nums[stack[-1]] <= nums[j]:
                l[stack.pop()] = j
            stack.append(j)

        for i in range(n):
            if left <= nums[i] <= right:
                res += (i-l[i])*(r[i]-i)
        return res

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值