• 力扣(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

  • 相关阅读:
    Shell Script注释和debug
    分布式系统中线程和进程的机制问题
    Aurora中的策略模式和模板模式
    spark读取和保存本机文件
    linux 使用 squid
    彻底理解Java并发:volatile关键字
    VivadoAndTcl: synth_ip
    Verilog:【6】PWM调制器(pwm_modulator.sv)
    帮助汽车制造业实现高精度脚垫上下料自动化
    2.Swift Tabbar的使用
  • 原文地址:https://blog.csdn.net/Innocence02/article/details/128012197