一道不知道错哪儿了的算法题
Posted 看,未来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道不知道错哪儿了的算法题相关的知识,希望对你有一定的参考价值。
感觉写这个标题好low啊,不过确实是还没想明白我的思路哪里有问题。
题目:最高频元素的频数
元素的 频数 是该元素在一个数组中出现的次数。
给你一个整数数组 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 <= nums.length <= 105
1 <= nums[i] <= 105
1 <= k <= 105
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:“滑动窗口”+“双指针“
乍一看,这不是“滑动窗口”+“双指针“吗,思路很明确啊。
首先,先排序,算出所有数到最后一个数的差值,并记录。
进入循环,如果差值大于给定值,则需要删掉一个元素来降低差值嘛。
那怎么删最经济实惠?当然是删掉一个数,能最大限度的降低差值嘛。
那删哪个数?其实也很好选,首尾挑一个。
挑哪个?比一下哪个划算不就好了嘛。
我的代码
所以代码也就出来了嘛:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int test(vector<int>& a, int k) {
sort(a.begin(), a.end());
int count = 0; //记录一个当前偏差值
int sz = a.size() - 1; //记录当前数量-1
int last = sz; //记录当前末尾位置
int first = 0; //记录当前起始位置
for (int i = 0;i < sz;i++) {
count += (a[last] - a[i]);
}
//count<=k为退出循环条件
while (count > k) {
if ((a[last] - a[first]) >= sz * (a[last] - a[last - 1])) { //当删除第一个元素有利时
count -= (a[last] - a[first]);
first++;
}
else { //当删除最后一个元素有利时
count -= sz * (a[last] - a[last - 1]);
last--;
}
}
return last-first+1;
}
int main() {
vector<int> a = {9930,9923,9983,9997,9934,9952,9945,9914,9985,9982,9970,9932,9985,9902,9975,9990,9922,9990,9994,9937,9996,9964,9943,9963,9911,9925,9935,9945,9933,9916,9930,9938,10000,9916,9911,9959,9957,9907,9913,9916,9993,9930,9975,9924,9988,9923,9910,9925,9977,9981,9927,9930,9927,9925,9923,9904,9928,9928,9986,9903,9985,9954,9938,9911,9952,9974,9926,9920,9972,9983,9973,9917,9995,9973,9977,9947,9936,9975,9954,9932,9964,9972,9935,9946,9966};
int b = test(a, 3056);
cout << b << endl;
return 0;
}
但是这个测试案例就是会少两个,数少的时候还好调啦,数一大,哪里去算哪。。。。
别人的代码
typedef long long ll;
int maxFrequency(vector<int>& nums, int k) {
int n = nums.size();
sort(nums.begin(), nums.end());
vector <ll> sum(n);
sum[0] = nums[0];
for(int i = 1; i < n; i++) sum[i] += sum[i - 1] + nums[i];
int ans = 0;
for(int i = 0; i < n; i++) {
int l = 0, r = i, res = -1;
while(l <= r) {
int mid = ((l ^ r) >> 1) + (l & r); // (l + r) / 2
if(nums[i] * (ll)(i - mid + 1) - sum[i] + (mid > 0 ? sum[mid - 1] : 0) <= k) {
r = mid - 1;
res = mid;
}
else l = mid + 1;
}
if(res != -1) ans = max(ans, i - res + 1);
}
return ans;
}
以上是关于一道不知道错哪儿了的算法题的主要内容,如果未能解决你的问题,请参考以下文章
表妹问我一道大一算法题,想半天不知道怎么以简单点的方式帮她解决。。。,最后看到答案很惭愧。