• 力扣(LeetCode)795. 区间子数组个数(C++)


    模拟

    有一种构想,只考虑上边界,在小边界和大边界之间的连续子数组个数 = = =小于等于大边界的连续子数组个数 − - 小于小边界的连续子数组个数。

    连续子数组个数计算公式 s u m = n × ( n + 1 ) 2 sum = \dfrac{n\times (n+1)}{2} sum=2n×(n+1)
    长度为 n n n 的小于某上界的区间,我们可以从中取 n / ( n − 1 ) / ( n − 2 ) … / 2 / 1 n/(n-1)/(n-2)\dots/2/1 n/(n1)/(n2)/2/1 个数,构成连续子数组,分别有 1 / 2 / 3 … / ( n − 1 ) / n 1/2/3\dots/(n-1)/n 1/2/3/(n1)/n 个数组,总共 n × ( n + 1 ) 2 \dfrac{n\times (n+1)}{2} 2n×(n+1) 个连续子数组。

    统计 n u m s nums nums 所有区间,分别求出连续子数组个数, a n s = ∑ s u m ans = \sum sum ans=sum 就是 n u m s nums nums 内所有连续子数组个数。

    提示 : 文中所有公式成立的前提是只考虑小于某边界。

    C++

    class Solution {
    public:
        int calc(vector<int> &nums,int k){
            int ans = 0;
            for(int i= 0;i<nums.size();i++){
                if(nums[i]>k) continue;
                int j = i+ 1;
                while(j<nums.size()&&nums[j]<=k) j++;
                ans += (long long)(j-i)*(j-i+1)/2;
                i = j;
            }
            return ans;
        }
        int numSubarrayBoundedMax(vector<int>& nums, int left, int right) {
            return calc(nums,right) - calc(nums,left -1);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    时间复杂度 O ( n ) O(n) O(n) : 一次遍历 n u m s nums nums 即可求出小于某边界的连续子数组个数,遍历较大边界和较小边界的总时间复杂度 O ( 2 × n ) O(2\times n) O(2×n) ,忽略常数时间复杂度 O ( n ) O(n) O(n)

    空间复杂度 O ( 1 ) O(1) O(1) : 只用到常量级空间。

    致语

    理解思路很重要!
    欢迎读者在评论区留言,答主看到就会回复的。

    AC

    AC

  • 相关阅读:
    LLM微调(一)| 单GPU使用QLoRA微调Llama 2.0实战
    基于nodejs的预约上门维修服务系统
    存储性能测试
    WPF动画教程(PointAnimationUsingPath的使用)
    Linux驱动开发——(五)内核中断
    SOFA Weekly|Go 代码城市、本周 Contributor & QA
    Intel酷睿和AMD锐龙
    go数组array
    小程序canvas层级过高真机遮挡组件的解决办法
    基于SSH的酒店管理系统
  • 原文地址:https://blog.csdn.net/Innocence02/article/details/128012197