c语言 100137. 统计最大元素出现至少 K 次的子数组

给你一个整数数组 nums 和一个 正整数 k 。

请你统计有多少满足 「 nums 中的 最大 元素」至少出现 k 次的子数组,并返回满足这一条件的子数组的数目。

子数组是数组中的一个连续元素序列。

示例 1:

输入:nums = [1,3,2,3,3], k = 2
输出:6
解释:包含元素 3 至少 2 次的子数组为:[1,3,2,3]、[1,3,2,3,3]、[3,2,3]、[3,2,3,3]、[2,3,3] 和 [3,3] 。

示例 2:

输入:nums = [1,4,2,1], k = 3
输出:0
解释:没有子数组包含元素 4 至少 3 次。
提示:
  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 106
  • 1 <= k <= 105

乘法原理:做一件事,完成它需要分成n个步骤,做第一 步有m1种不同的方法,做第二步有m2种不同的方法,……,做第n步有mn种不同的方法。那么完成这件事共有 N=m1×m2×m3×…×mn 种不同的方法。 和加法原理是数学概率方面的基本原理。

滑窗算法 ,设最大值max,max的下标数组a,n个max下标,最小符合要求的子串为a[i]....a[i+k-1],包含该子串的子串数量,根据乘法原理,有(n-a[ik-1])*(a[i]-a[i-1])个,依次枚举左指针,累加得结果。

注意每次的乘法要用long long类型做,int可能会不够

a[0]=-1,如果第一个max下标为0,则最多进行一步变化来使变化后字串符合要求

long long countSubarrays(int* nums, int numsSize, int k) {
    int max=0;
    for(int i=0;i<numsSize;i++)if(max<nums[i])max=nums[i];
    int n=0;
    int  *a=(int *)malloc((numsSize+1)*sizeof(int ));
    long long re=0;
    a[n++]=-1;
    for(int i=0;i<numsSize;i++)if(max==nums[i])a[n++]=i;
    int i=1,j=i+k-1;
    long long b;
    while(j<n){
        b=(numsSize-a[j]);
           re+=b*(a[i]-a[i-1]);
            i++;
            while(j-i+1<k)j++;           
    }
    return re;
}

posted @ 2023-12-10 17:25  CV小能手chh  阅读(14)  评论(0)    收藏  举报  来源