思路:一开始我是使用暴力解法,先排序,一个一个元素遍历,从该元素最近的一个数(左边)往左求它们的差值和直到超出了目标值k,再存所包含的最大元素个数,然后就超出时间限制了:
class Solution {
public:
int maxFrequency(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
int result(1);
for(int i=1;i<nums.size();++i)
{
int j=i-1;
int n=k;
int mid(1);
while(j>=0)
{
if(nums[i]-nums[j]<=n)
{
++mid;
n-=(nums[i]-nums[j]);
--j;
}
else break;
}
if(result<mid) result=mid;
}
return result;
}
};
然后看了解题区的思路,利用滑动窗口,不断将窗口右边界右移,如果超出了k就向右移动左边界,如下
class Solution {
public:
int maxFrequency(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());//要先排序
int result(1);//记录结果
int mid(1);//存放中途中出现的总个数
long long t=k;//存放还能被允许的差值和
for(int i=1,j=0;i<nums.size();)
{
//对于numsp[i]其实还未放入窗口中,即正在考虑如何放
//所以目前的状况是,窗口内的所有数能够与nums[i-1]相等
//因此要判断能不能都与nums[i]相等,就要判断达到nums[i]的差值和是否在t内
//因为目前大家都等于了nums[i-1],所以还需要的差值和就为如下判断条件里的式子
//这里可能会超出int的范围,所以要用long long类型
if((long long)(nums[i]-nums[i-1])*(i-j)<=t)
{
//在能承受范围内,就要减去这部分代价,目前所有数就等于了nums[i]
t-=(long long)(nums[i]-nums[i-1])*(i-j);
//nums[i]加入了窗口
++mid;
//判断下一个数
++i;
}
//如果超出了接受范围
else
{
//这里的话目前窗口达到了一个上限,所以需要判断保留最大值
if(mid>result) result=mid;
//这里是把最左边界的元素去除,所以要加上差值
t+=(nums[i-1]-nums[j]);
//左边界右移
++j;
//失去一个元素
--mid;
}
}
//返回最大
return max(result,mid);
}
};