力扣795.区间子数组个数 | 树状数组解法

Problem: 795. 区间子数组个数

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

示例 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

文章目录

思路

  • 思路本质和官方题解的一次遍历做法一样。
  • 我看到区间就往树状数组想,确实能做,没想到ac完看到官方题解,时间、空间复杂度很少就ac了。所以就当为此题提供一种新的解决方法吧。

复杂度

时间复杂度:

O ( n l o g n ) O(nlogn) O(nlogn)

空间复杂度:

O ( n ) O(n) O(n)

Code

const int MAX = 1e5+5;
int tr[MAX];
int lowbit(int x){return x&-x;}
void add(int x,int val){
    for(;x<MAX;x+=lowbit(x))tr[x]+=val;
}
// query表示的状态:以这个数作末尾有几种情况
int query(int x){
    int res=0;
    for(;x>0;x-=lowbit(x)){
        res+=tr[x];
    }
    return res;
}
class Solution {
public:
    // 单个区间的子数组个数(已保证该区间的所有数都<=right)
    int numArray(vector<int>& nums, int left) {
        memset(tr,0,sizeof(tr));
        int res=0;
        int lastIndex=-1;// lastIndex记录符合[left,right]的数的下标,不断更新
        for(int i=1;i<=nums.size();++i){// 树状数组下标从1开始
            add(i,1);
            // 如果数字小于left,就往左找到第一个符合[left,right]的数,结果加上他本身存在的情况数
            if(nums[i-1]<left&&lastIndex!=-1)res+=query(lastIndex);
            
            // 如果数字符合[left,right],则总数加上以这个数作末尾的情况
            if(nums[i-1]>=left){
                res+=query(i);
                lastIndex=i;
            }
        }

        return res;
    }
    int numSubarrayBoundedMax(vector<int>& nums, int left, int right) {
        int res=0;
        // 利用每个大于right的数去划分,得到多个子区间,对每个区间都使用numArray去计算该区间的数量,最后累加即可
        vector<int>tmp;
        for(auto num:nums){
            if(num<=right)tmp.emplace_back(num);
            else{
                if(tmp.size()>0){
                    res+=numArray(tmp,left);
                    tmp.clear();
                }
            }
        }
        if(tmp.size()>0){
            res+=numArray(tmp,left);
            tmp.clear();
        }
        return res;
    }
};

相关推荐

  1. 795.区间数组个数 | 树状数组解法

    2024-04-26 10:24:01       13 阅读
  2. 2762. 不间断数组

    2024-04-26 10:24:01       12 阅读
  3. 1248.统计优美数组

    2024-04-26 10:24:01       10 阅读
  4. 数组Array】-370 区间加法

    2024-04-26 10:24:01       50 阅读
  5. 100】9.和为k的数组

    2024-04-26 10:24:01       46 阅读
  6. 209-长度最小的数组

    2024-04-26 10:24:01       42 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-26 10:24:01       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-26 10:24:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-26 10:24:01       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-26 10:24:01       20 阅读

热门阅读

  1. 磨损对输送带安全的影响

    2024-04-26 10:24:01       33 阅读
  2. C#中的LINQ(Language-Integrated Query)

    2024-04-26 10:24:01       14 阅读
  3. 二叉树层次遍历

    2024-04-26 10:24:01       19 阅读
  4. 分布式与微服务区别?

    2024-04-26 10:24:01       11 阅读
  5. npm cnpm pnpm yarn 有什么区别? 哪个更好用呢?

    2024-04-26 10:24:01       15 阅读
  6. sklearn混淆矩阵的计算和seaborn可视化

    2024-04-26 10:24:01       19 阅读
  7. springboot+Vue实现分页

    2024-04-26 10:24:01       13 阅读
  8. 相交链表的判断(leetcode)

    2024-04-26 10:24:01       11 阅读
  9. 探索 Chrome 插件开发之旅

    2024-04-26 10:24:01       16 阅读