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 <= 1051 <= nums[i] <= 1061 <= 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;
}

浙公网安备 33010602011771号