文章目录
前言
今天算法的内容是:前缀和
一、最高频元素的频数
元素的 频数 是该元素在一个数组中出现的次数。给你一个整数数组 nums 和一个整数 k 。在一步操作中,你可以选择 nums 的一个下标,并**将该下标对应元素的值增加 1 。
执行最多 k 次操作后,返回数组中最高频元素的 最大可能频数 。
示例 1:
输入:nums = [1,2,4], k = 5
输出:3
解释:对第一个元素执行 3 次递增操作,对第二个元素执 2 次递增操作,此时 nums = [4,4,4] 。
4 是数组中最高频元素,频数是 3 。
示例 2:
输入:nums = [1,4,8,13], k = 5
输出:2
解释:存在多种最优解决方案:
- 对第一个元素执行 3 次递增操作,此时 nums = [4,4,8,13] 。4 是数组中最高频元素,频数是 2 。
- 对第二个元素执行 4 次递增操作,此时 nums = [1,8,8,13] 。8 是数组中最高频元素,频数是 2 。
- 对第三个元素执行 5 次递增操作,此时 nums = [1,4,13,13] 。13 是数组中最高频元素,频数是 2 。
示例 3:
输入:nums = [3,9,6], k = 2
输出:1
一、思路:
(1)题目没有说明数组是否有序,所以先进行一个递增排序(方便之后操作)
(2)因为可以任意分配k中数以增加数组中任意元素值,可从最小值开始分配并开始区间长度的增长~~(为什么从最小值开始呢?暂时还不是非常深入的清楚,就是挨个的运算吧)~~
(4)所以可以从排序后区间数组的最短前缀和下标开始循环递增
(5)对当前下标元素值和数组区间长度所乘得的理想数值(理想分配后的前缀和)与当前长度的实际大小进行一个相减(当前实际前缀和)设理想分配值 变量为 s,就可知该需要分配多少值,所以这是一个前缀和的问题
(6)然后与可分配的 k 值进行比较可知够不分配,不够分配就需要右移左区间边界的位置,改变左边界直到s<=k为止(现在不够,之后也是不够的,左区间右移后不会再次归零),减少频数,所以这又是一个区间范围的问题
(有点像游戏里面的属性加点呐 hh)
综上所诉:
·(1)需要用到 前缀统计区间大小 与 计算部分和的知识
·(2)需要用到 双指针处理 边界的问题的知识
二、源码
class Solution {
public:
int maxFrequency(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
long long sum[101001];
int i,j;
int ans=0;
int n=nums.size();
for(i=1;i<=n;i++){
sum[i]=sum[i-1]+nums[i-1];
}
i=0;
for(j=1;j<=n;j++){
long long s=(sum[j]-sum[j-1])*(j-i)-(sum[j]-sum[i]);
while(s>k){
i++;
s=(sum[j]-sum[j-1])*(j-i)-(sum[j]-sum[i]);
}
ans=max(ans,j-i);
}
return ans;
}
};
//英雄哥的代码啦hh
//争取有一天可以自己想出来hhh
三.知识点
(1)需要用到 前缀统计区间大小 与 计算处理区间部分和的知识
(2)需要用到 双指针处理 边界的知识