The frequency of an element is the number of times it occurs in an array.
You are given an integer array nums
and an integer k
. In one operation, you can choose an index of nums
and increment the element at that index by 1
.
Return the maximum possible frequency of an element after performing at most k
operations.
Example 1:
Input: nums = [1,2,4], k = 5
Output: 3
Explanation: Increment the first element three times and the second element two times to make nums = [4,4,4].
4 has a frequency of 3.
Example 2:
Input: nums = [1,4,8,13], k = 5
Output: 2
Explanation: There are multiple optimal solutions:
- Increment the first element three times to make nums = [4,4,8,13]. 4 has a frequency of 2.
- Increment the second element four times to make nums = [1,8,8,13]. 8 has a frequency of 2.
- Increment the third element five times to make nums = [1,4,13,13]. 13 has a frequency of 2.
Example 3:
Input: nums = [3,9,6], k = 2
Output: 1
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 105
1 <= k <= 105
题目链接:https://leetcode.com/problems/frequency-of-the-most-frequent-element/submissions/
题目大意:给一个数组,每个数字可以加值,总累加值不得超过k,求加完后频数最大的数字的频数
题目分析:提交完看到击败率,就知道不是正解了,看了下related topic是贪心,回头再想。。
当前做法:排序求前缀和,遍历nums,分别计算为了让nums[i]频数尽可能大时其最大的频数,因为前缀和有序,故可二分,二分点(mid)到当前枚举点(curP)这段区间均加到当前枚举点值所需的数值总量可以O(1)算出,通过前缀和可以求出这段区间的和,又知道枚举点值(curV)及区间长度(curP - mid + 1),见cal()方法。这里有个关键优化,就是当两个连续数字相同时,只需算一次即可(显然)
34ms,时间击败42.27%
class Solution {
public long cal(long[] presum, int mid, int curP, long curV) {
long sum = (mid == 0) ? presum[curP] : presum[curP] - presum[mid - 1];
//System.out.println("curV = " + curV + " curP = " + curP + " mid = " + mid + " sum = " + sum + " need = " + ((curP - mid + 1) * curV - sum));
return (long)(curP - mid + 1) * curV - sum;
}
public int bsearch(long[] presum, int n, int k, int curP, int curV) {
int l = 0, r = curP, mid = 0, pos = curP;
while (l <= r) {
mid = (l + r) >> 1;
if (cal(presum, mid, curP, curV) > k) {
l = mid + 1;
} else {
pos = mid;
r = mid - 1;
}
}
//System.out.println("curP = " + curP + " pos = " + pos);
return curP - pos + 1;
}
public int maxFrequency(int[] nums, int k) {
Arrays.sort(nums);
int n = nums.length;
long[] presum = new long[n];
presum[0] = nums[0];
for (int i = 1; i < n; i++) {
presum[i] = presum[i - 1] + nums[i];
//System.out.println("sum[" + i + "] = " + presum[i]);
}
//System.out.println("biggest = " + presum[n - 1]);
int ans = 0;
for (int i = n - 1; i >= 0; i--) {
if (i < n - 1 && nums[i] == nums[i + 1]) {
continue;
}
ans = Math.max(ans, bsearch(presum, n, k, i, nums[i]));
}
return ans;
}
}