Taro Logo

Frequency of the Most Frequent Element

Medium
Meta logo
Meta
2 views
Topics:
ArraysSliding WindowsGreedy Algorithms

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.

For example:

Given nums = [1,2,4] and k = 5, return 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.

Given nums = [1,4,8,13] and k = 5, return 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.

Given nums = [3,9,6] and k = 2, return 1.

How would you efficiently solve this problem?

Solution


Naive Approach

A brute force approach would involve iterating through all possible subarrays and, for each subarray, calculating the number of operations needed to make all elements equal to the largest element in that subarray. We would then keep track of the maximum frequency seen so far.

This approach is highly inefficient due to the nested loops required to generate subarrays and calculate the cost of operations.

Optimal Approach: Sliding Window

A more efficient solution involves sorting the array and using a sliding window. The core idea is to maintain a window such that the cost of making all elements in the window equal to the largest element (rightmost after sorting) is less than or equal to k.

Here's a breakdown of the algorithm:

  1. Sort the Array: Sort the input array nums in ascending order.
  2. Initialize Window: Use two pointers, left and right, to define the sliding window. Initialize both to 0.
  3. Expand Window: Move the right pointer to expand the window. For each new element included in the window, update the total cost needed to make all elements in the window equal to the rightmost element.
  4. Shrink Window: If the total cost exceeds k, move the left pointer to shrink the window until the cost is within the limit.
  5. Update Max Frequency: After each adjustment of the window, update the maximum frequency seen so far (which is the current window size).

Edge Cases

  • If the input array is empty, return 0.
  • If k is 0, the maximum frequency is 1 if all elements are same otherwise 0.
  • If k is large enough, the maximum frequency is just the length of the array (if all elements can be made equal).

Code

def max_frequency(nums, k):
 nums.sort()
 left = 0
 total_cost = 0
 max_freq = 0

 for right in range(len(nums)):
 total_cost += (nums[right] - nums[right - 1]) * (right - left) if right > 0 else 0

 while total_cost > k:
 total_cost -= nums[right] - nums[left]
 left += 1

 max_freq = max(max_freq, right - left + 1)

 return max_freq
import java.util.Arrays;

class Solution {
 public int maxFrequency(int[] nums, int k) {
 Arrays.sort(nums);
 int left = 0;
 long totalCost = 0;
 int maxFreq = 0;

 for (int right = 0; right < nums.length; right++) {
 if (right > 0) {
 totalCost += (long) (nums[right] - nums[right - 1]) * (right - left);
 }

 while (totalCost > k) {
 totalCost -= nums[right] - nums[left];
 left++;
 }

 maxFreq = Math.max(maxFreq, right - left + 1);
 }

 return maxFreq;
 }
}

Complexity Analysis

  • Time Complexity: O(n log n) due to sorting the array. The sliding window part is O(n), but it's dominated by the sorting.
  • Space Complexity: O(1) or O(n), depending on the sorting algorithm used. In-place sorting algorithms have O(1) space complexity, while others (like merge sort) might use O(n).