AlgoMaster Logo

Frequency of the Most Frequent Element

mediumFrequencyUpdated September 21, 2026

Understanding the Problem

We have an array of integers and a budget of k increment operations. Each operation adds 1 to any element we choose. We want to maximize how many elements share the same value after using at most k operations.

We can only increment elements, never decrement them. So to make a group of elements equal, they must all be raised to the value of the largest element in that group. Overshooting past that largest value only wastes operations, so the target is always some value already present in the array.

The problem reduces to: pick a target value equal to one of the array elements, and find how many smaller elements we can afford to raise up to that target within the budget of k.

Sorting makes this tractable. Once the array is sorted, the elements closest in value to a target sit right next to it, and those are the cheapest to raise. The problem becomes finding the longest window in a sorted array where the cost of raising every element to the window's maximum stays within k.

Key Constraints:

  • 1 <= nums.length <= 10^5 --> We need O(n log n) or better. An O(n^2) approach approaching 10^10 operations would be too slow.
  • 1 <= nums[i] <= 10^5 and 1 <= k <= 10^5 --> A window of up to 10^5 elements valued up to 10^5 gives a cost of up to 10^10, which overflows a 32-bit integer. The window sum and cost must use a 64-bit type.

Approach 1: Brute Force (Check Every Subarray)

Intuition

Sort the array, then for every possible target element nums[right], count how many elements to its left we can afford to raise up to that value. Iterate backward from right, accumulating the cost of each increment, and stop once the budget is exhausted.

Working backward from the target picks up the cheapest elements first, since in sorted order the elements nearest nums[right] need the fewest increments to reach it. Including those before the farther ones maximizes the count for any fixed budget.

Algorithm

  1. Sort the array in ascending order.
  2. For each index right from 0 to n-1, treat nums[right] as the target value.
  3. For each right, iterate backward from right-1 to 0, accumulating the cost to raise each element to nums[right].
  4. Stop when the accumulated cost exceeds k.
  5. The number of elements in this window (including nums[right]) is a candidate answer.
  6. Return the maximum candidate across all choices of right.

Visualization and Code

Loading animation...

For each target element, this scans backward through the array and recomputes the cost from scratch. Maintaining a running window sum and only moving the left boundary when the budget is exceeded removes that repeated work.

Approach 2: Sorting + Sliding Window

Intuition

After sorting, the cheapest elements to raise to any target are its immediate neighbors, so the affordable elements for a given target form a contiguous block. That maps directly onto a sliding window over the sorted array.

For a window [left, right], raising every element to nums[right] (the largest in the window) costs nums[right] * windowSize - windowSum. Each element nums[i] needs nums[right] - nums[i] increments to reach the target; summing that over the window gives nums[right] * windowSize minus the sum of the window.

The window expands right one step at a time, adding the new element to the running sum. When the cost exceeds k, it shrinks from the left by removing nums[left] from the sum and advancing left. The largest window size reached is the answer.

Algorithm

  1. Sort the array in ascending order.
  2. Initialize left = 0, windowSum = 0, maxFreq = 0.
  3. For each right from 0 to n-1:
    1. Add nums[right] to windowSum.
    2. While the cost nums[right] * (right - left + 1) - windowSum > k, subtract nums[left] from windowSum and increment left.
    3. Update maxFreq = max(maxFreq, right - left + 1).
  4. Return maxFreq.

Visualization and Code

Loading animation...

The sliding window is already O(n log n), dominated by sorting. The same time bound is reachable from a different angle: fix each right endpoint and binary search for how far left the window can extend, using prefix sums to evaluate each candidate in constant time.

Approach 3: Sorting + Prefix Sum + Binary Search

Intuition

After sorting, for each index right, find the smallest index left such that the cost of making all elements in [left, right] equal to nums[right] is at most k. The window size right - left + 1 for that smallest left is the best frequency achievable with nums[right] as the target.

The cost is nums[right] * (right - left + 1) - sum(nums[left..right]). Precomputing prefix sums makes sum(nums[left..right]) an O(1) lookup. As left moves closer to right, the window holds fewer and cheaper-to-raise elements, so the cost decreases monotonically. That monotonicity allows a binary search for the smallest affordable left.

The approach builds a prefix sum array, then for each right binary searches for the farthest-left position that keeps the cost within k.

Algorithm

  1. Sort the array.
  2. Build a prefix sum array where prefix[i] = sum of nums[0..i-1].
  3. For each right from 0 to n-1:
    1. Binary search for the smallest left in [0, right] such that nums[right] * (right - left + 1) - (prefix[right+1] - prefix[left]) <= k.
    2. The window size is right - left + 1.
  4. Return the maximum window size.

Visualization and Code

Loading animation...