一道不知道错哪儿了的算法题

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;
    }

以上是关于一道不知道错哪儿了的算法题的主要内容,如果未能解决你的问题,请参考以下文章

一道不知道哪儿的练习题

表妹问我一道大一算法题,想半天不知道怎么以简单点的方式帮她解决。。。,最后看到答案很惭愧。

表妹问我一道大一算法题,想半天不知道怎么以简单点的方式帮她解决。。。,最后看到答案很惭愧。

Spring解决循环依赖的思路竟然来自于一道算法题

一道约瑟夫算法题的简单设计

运行maven install时候报错了。不知道哪儿错了