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

2023-10-27

模拟

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

连续子数组个数计算公式 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);
    }
};

时间复杂度 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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

力扣(LeetCode)795. 区间子数组个数(C++) 的相关文章

随机推荐