首页 > 其他分享 >795.区间子数组个数 (Medium)

795.区间子数组个数 (Medium)

时间:2023-06-13 16:48:18浏览次数:47  
标签:795 Medium idx nums int top 个数 stk lidx

问题描述

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

生成的测试用例保证结果符合 32-bit 整数范围。

示例 1:

输入:nums = [2,1,4,3], left = 2, right = 3
输出:3
解释:满足条件的三个子数组:[2], [2, 1], [3]

示例 2:

输入:nums = [2,9,2,5,6], left = 2, right = 8
输出:7

提示:

  • 1 <= nums.length <= 10⁵
  • 0 <= nums[i] <= 10⁹
  • 0 <= left <= right <= 10⁹

解题思路

单调栈

当我们看到这种连续区间中的最大值的题目时,就可以考虑使用单调栈。

nums[idx],我们需要找到以 nums[idx] 为最大值的子数组的数量,设 lidx 为满足 nums[l] >= nums[idx]l < idx 的最大的 l;设 ridx 为满足 nums[r] > nums[idx]r > idx 中的最小的 r。我们要做的就是枚举满足 0 <= idx < n 的所有的 idx,找到对应的 lidxridx,从而计算出子数组的数量。

子数组的数量为 (ridx - idx) * (idx - lidx)

在本题中,我们可以考虑使用从栈底到栈顶单调递减的栈,来求出 ridxlidx。注意,栈中的元素是索引 idx。枚举 i,当 nums[i] > nums[stk.top()] 时,对 idx = stk.top(),将栈顶元素出栈,ridx = ilidx 为新栈顶,如果栈为空,则 lidx = -1

当枚举完 i 之后,对栈中剩余元素,idx = stk.top(), ridx = n,将栈中元素出栈,如果栈为空,lidx = -1,否则 lidx = stk.top();

双指针

代码

单调栈

class Solution {
  public:
    int numSubarrayBoundedMax(vector<int> &nums, int left, int right) {
        // 单调栈,以 nums[i] 为最大值的子数组的个数
        // 栈底到栈顶单调递减
        int res = 0;
        stack<int> stk;
        int n = nums.size();
        for (int i = 0; i < n; ++i) {
            while (!stk.empty() && nums[i] > nums[stk.top()]) {
                int idx = stk.top();
                int len1 = i - idx;
                int val = nums[idx];
                stk.pop();
                int len2 = stk.empty() ? idx + 1 : idx - stk.top();
                if (val <= right && val >= left) {
                    res += len1 * len2;
                }
            }
            stk.push(i);
        }
        while (!stk.empty()) {
            int idx = stk.top();
            int len1 = n - idx;
            int val = nums[idx];
            stk.pop();
            int len2 = stk.empty() ? idx + 1 : idx - stk.top();
            if (val <= right && val >= left) {
                res += len1 * len2;
            }
        }
        return res;
    }
};

标签:795,Medium,idx,nums,int,top,个数,stk,lidx
From: https://www.cnblogs.com/zwyyy456/p/17478032.html

相关文章

  • 802.找到最终的安全状态 (Medium)
    问题描述802.找到最终的安全状态(Medium)有一个有n个节点的有向图,节点按0到n-1编号。图由一个索引从0开始的2D整数数组graph表示,graph[i]是与节点i相邻的节点的整数数组,这意味着从节点i到graph[i]中的每个节点都有一条边。如果一个节点没有连出的有......
  • 2718. 查询后矩阵的和 (Medium)
    问题描述2718.查询后矩阵的和(Medium)给你一个整数n和一个下标从0开始的二维数组queries,其中queries[i]=[typeᵢ,indexᵢ,valᵢ]。一开始,给你一个下标从0开始的nxn矩阵,所有元素均为0。每一个查询,你需要执行以下操作之一:如果typeᵢ==0,将第index......
  • 28.找出字符串中第一个匹配项的下标 (Medium)
    问题描述28.找出字符串中第一个匹配项的下标(Medium)给你两个字符串haystack和needle,请你在haystack字符串中找出needle字符串的第一个匹配项的下标(下标从0开始)。如果needle不是haystack的一部分,则返回-1。示例1:输入:haystack="sadbutsad",needle="sad......
  • 373. 查找和最小的 K 对数字 (Medium)
    问题描述373.查找和最小的K对数字(Medium)给定两个以升序排列的整数数组nums1和nums2,以及一个整数k。定义一对值(u,v),其中第一个元素来自nums1,第二个元素来自nums2。请找到和最小的k个数对(u₁,v₁),(u₂,v₂)...(uₖ,vₖ)。示例1:输入:nums1......
  • 代码随想录算法训练营第五天| 242.有效的字母异位词 , 349. 两个数组的交集 , 202. 快
    242.有效的字母异位词 繁冗版:1,思路:先建立两个map,对应两个字符串对应的字符,同时对他们进行计数,如果这两个数字相等,那么就是相等2,代码1boolisAnagram_complicate(strings,stringt)2{3unordered_map<char,int>existedCharBys;45for(autoch......
  • 2023-06-12:如果一个正整数自身是回文数,而且它也是一个回文数的平方,那么我们称这个数为
    2023-06-12:如果一个正整数自身是回文数,而且它也是一个回文数的平方,那么我们称这个数为超级回文数。现在,给定两个正整数L和R(以字符串形式表示),返回包含在范围[L,R]中的超级回文数的数目。输入:L="4",R="1000"。输出:4。答案2023-06-12:该算法的基本思路是从较小的回文数开始......
  • 2023-06-12:如果一个正整数自身是回文数,而且它也是一个回文数的平方,那么我们称这个数为
    2023-06-12:如果一个正整数自身是回文数,而且它也是一个回文数的平方,那么我们称这个数为超级回文数。现在,给定两个正整数L和R(以字符串形式表示),返回包含在范围[L,R]中的超级回文数的数目。输入:L="4",R="1000"。输出:4。答案2023-06-12:该算法的基本思路是从较小的回......
  • LeetCode/区间子数组个数
    给你一个整数数组nums和两个整数:left及right找出nums中连续、非空且其中最大元素在范围[left,right]内的子数组,并返回满足条件的子数组的个数1.遍历区间右端点+同时记录满足条件的左边点位数组中不能含有大于right的元素,且至少含有一个处于[left,right]区间的元......
  • 315. 计算右侧小于当前元素的个数
    labuladong题解难度困难987给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于 nums[i] 的元素的数量。 示例1:输入:nums=[5,2,6,1]输出:[2,1,1,0]解释:5的右侧有2个更小的元素(2和......
  • AcWing——凑数(二进制中1的个数)
    1、题目初始时,n=0。每一轮操作都要依次完成两个步骤:第一步,任选一个非负整数a,将n增加a,这一步所需付出的代价为a。第二步,将n乘以2,这一步无需付出任何代价。你可以不断重复上述操作。给定一个整数x,你的任务是使n在某一步操作后(不一定是某一轮结束后)恰好等于x且付出的总代......