Loading problems...
TL;DR: Sort the input array and use a sliding window to find the longest contiguous subarray where the cost to make all elements equal to the largest element does not exceed k.
In the Frequency of the Most Frequent Element problem, you are provided with an integer array nums and a budget k. You are allowed to increment any element in the array by 1, and each increment costs 1 unit of your budget. The goal is to determine the maximum frequency of any single element possible after performing operations, provided the total cost is less than or equal to k.
This is a popular interview question that tests your ability to optimize brute force logic into linear time complexity using sorting and windowing techniques.
The naive approach involves trying to make every element in the array the "most frequent" target. Since we can only increment numbers (not decrement), it is logical to sort the array first. If we choose an element nums[i] as our target value, we should look at elements smaller than nums[i] (i.e., , , etc.) and increment them to match until our budget is exhausted.
nums[i-1]nums[i-2]nums[i]kPseudo-code:
textSort nums Initialize max_frequency = 1 For i from 0 to length(nums) - 1: target = nums[i] current_cost = 0 current_frequency = 1 For j from i - 1 down to 0: cost_to_increment = target - nums[j] If current_cost + cost_to_increment <= k: current_cost += cost_to_increment current_frequency += 1 Else: Break inner loop Update max_frequency with current_frequency
The brute force solution requires sorting, which takes . However, the nested loops result in complexity. Given the constraints where can be up to , an algorithm performs roughly operations, which will result in a Time Limit Exceeded (TLE) error. We need a solution closer to or .
The key intuition relies on the properties of a sorted array. Once nums is sorted, the optimal elements to increment to reach a target value nums[R] are the elements immediately preceding it (nums[R-1], nums[R-2], etc.). These elements are closest in value to nums[R], minimizing the cost of operations.
If we consider a window defined by indices [L, R], we want to treat nums[R] as the target value for all elements in this window. The cost to transform all elements in nums[L...R] to nums[R] can be calculated in time if we maintain a running sum of the window.
The Condition:
To make all elements in the window [L, R] equal to nums[R], the total sum required is nums[R] * window_length. The operations needed (cost) is the difference between this target sum and the actual sum of the elements currently in the window.
The Invariant:
We expand R to try and increase the frequency. If the calculated Cost exceeds k, the window is invalid. We must then increment L to shrink the window from the left, reducing the cost, until the condition is met again.
Visual Description:
Imagine the sorted array values plotted as vertical bars on a 2D graph. A sliding window [L, R] selects a range of these bars. The value nums[R] creates a horizontal "ceiling" extending leftwards to L. The empty space between this ceiling and the tops of the bars within [L, R] represents the cost to increment those numbers. As the right pointer moves to a taller bar, the ceiling rises, drastically increasing the empty space (cost). If this empty space area exceeds k, the left pointer moves right, removing the shortest bars from the calculation to reduce the total area.

Consider nums = [1, 2, 4], k = 5.
nums is already [1, 2, 4].L = 0, total = 0, max_freq = 0.total becomes 1.[1]. Target 1. Length 1.1 * 1 - 1 = 0. . Valid.max_freq = max(0, 1) = 1.total becomes 1 + 2 = 3.[1, 2]. Target 2. Length 2.2 * 2 - 3 = 1. . Valid.max_freq = max(1, 2) = 2.total becomes 3 + 4 = 7.[1, 2, 4]. Target 4. Length 3.4 * 3 - 7 = 5. . Valid.max_freq = max(2, 3) = 3.Consider nums = [1, 4, 8, 13], k = 5.
[4, 8] (indices 1 to 2). total = 12.8. Length 2. Cost 16 - 12 = 4 <= 5. Valid.total becomes 12 + 13 = 25.[4, 8, 13] (indices 1 to 3). Target 13. Length 3.13 * 3 - 25 = 14. . Invalid.nums[L] (which is 4). total becomes 21. L becomes 2.[8, 13]. Target 13. Length 2.13 * 2 - 21 = 5. . Valid.max_freq = max(..., 2).The algorithm relies on the fact that for any fixed right endpoint R (where nums[R] is the target value), there exists a unique smallest left endpoint L such that the cost to convert nums[L...R] to nums[R] is .
Because the array is sorted, adding an element to the left of the window always increases the cost, and removing an element from the left always decreases the cost. This monotonicity allows us to use a sliding window. By iterating R across the entire array and maintaining the optimal L for each R, we exhaustively check the maximum possible frequency ending at every possible position. The global maximum of these local maxima is the correct answer.
cpp#include <vector> #include <algorithm> using namespace std; class Solution { public: int maxFrequency(vector<int>& nums, int k) { sort(nums.begin(), nums.end()); long long total = 0; int left = 0; int maxFreq = 0; for (int right = 0; right < nums.size(); ++right) { total += nums[right]; // Current window size: right - left + 1 // Target sum: nums[right] * window_size // Operations needed: Target sum - total // Use long long for the calculation to avoid overflow long long windowSize = right - left + 1; long long cost = (long long)nums[right] * windowSize - total; while (cost > k) { total -= nums[left]; left++; // Recalculate cost for the new window size windowSize = right - left + 1; cost = (long long)nums[right] * windowSize - total; } maxFreq = max(maxFreq, (int)windowSize); } return maxFreq; } };
javaimport java.util.Arrays; class Solution { public int maxFrequency(int[] nums, int k) { Arrays.sort(nums); long total = 0; int left = 0; int maxFreq = 0; for (int right = 0; right < nums.length; right++) { total += nums[right]; // Calculate cost: (target * length) - current_sum // Use long to prevent integer overflow long target = nums[right]; long windowLength = right - left + 1; // While cost exceeds k, shrink window from the left while (target * windowLength - total > k) { total -= nums[left]; left++; windowLength = right - left + 1; } maxFreq = Math.max(maxFreq, (int)windowLength); } return maxFreq; } }
pythonclass Solution: def maxFrequency(self, nums: list[int], k: int) -> int: nums.sort() left = 0 total = 0 max_freq = 0 for right in range(len(nums)): total += nums[right] # Condition: (target * length) - sum <= k # Target is nums[right] while nums[right] * (right - left + 1) - total > k: total -= nums[left] left += 1 max_freq = max(max_freq, right - left + 1) return max_freq
L and R pointers move at most times. This part is .The Sliding Window - Variable Size (Condition-Based) pattern is versatile and appears in many standard interview problems.
Mastering the mechanics of the "expand-validate-shrink" loop in this problem directly aids in solving these related challenges.
nums[right] * window_length can exceed the limit of a 32-bit signed integer (2^31 - 1). In C++ and Java, ensure you use long or long long for these calculations.[L, R] are not necessarily the ones closest to nums[R]. Sorting groups numbers by magnitude, ensuring that a contiguous subarray represents the minimal cost to equalize values.(nums[right] * length) - current_window_sum. Ensure you update total correctly when incrementing left.