Maximum Frequency of an Element After Performing Operations II

Hard
Watch on YouTube ↗

Solution

class Solution {
    public int maxFrequency(int[] nums, int k, int numOperations) {

        // Maps to track frequency of original numbers and range updates
        Map<Integer, Integer> freq = new HashMap<>();  // original array numbers
        Map<Integer, Integer> diff = new HashMap<>();  // difference map for line sweep
        List<Integer> points = new ArrayList<>();      // all range boundaries + nums

        // Step 1: Build frequency and range difference maps
        for (int num : nums) {
            freq.put(num, freq.getOrDefault(num, 0) + 1);

            // Each number contributes +1 at (num - k) and -1 at (num + k + 1)
            diff.put(num - k, diff.getOrDefault(num - k, 0) + 1);
            diff.put(num + k + 1, diff.getOrDefault(num + k + 1, 0) - 1);

            // Collect key points for sweeping
            points.add(num);
            points.add(num - k);
            points.add(num + k + 1);
        }

        // Step 2: Sort and remove duplicates (coordinate compression)
        Collections.sort(points);
        int sz = 0;
        for (int i = 0; i < points.size(); i++) {
            if (i == 0 || !points.get(i).equals(points.get(i - 1))) {
                points.set(sz++, points.get(i));
            }
        }

        // Step 3: Line sweep to find max achievable frequency
        int ans = 0, common = 0;
        for (int i = 0; i < sz; i++) {
            int p = points.get(i);
            common += diff.getOrDefault(p, 0); // active count at this point

            int cur = freq.getOrDefault(p, 0); // current frequency
            int nearby = common - cur;         // elements that can be moved here
            int possible = cur + Math.min(nearby, numOperations);

            ans = Math.max(ans, possible);
        }

        return ans;
    }
}
/*
 * 
 * nums = [2, 4, 5]
k = 2
numOperations = 1
2 → [0 --- 4] → [0 -- 5)
4 → [2 --- 6] → [2 -- 7)
5 → [3 --- 7] → [3 -- 8)

Number 2:  [0 ======== 4]
             ↑---------↑
Number 4:      [2 ======== 6]
                 ↑---------↑
Number 5:        [3 ======== 7]
                   ↑---------↑

                   0 → +1
2 → +1
3 → +1
5 → -1
7 → -1
8 → -1

[0, 2, 3, 4, 5, 6, 7, 8]


| i | count | freq[i] | nearby | possible (= freq + min(nearby, ops)) |
| - | ----- | ------- | ------ | ------------------------------------ |
| 0 | 1     | 0       | 1      | 1                                    |
| 2 | 2     | 1       | 1      | 2                                    |
| 3 | 3     | 0       | 3      | 1                                    |
| 4 | 3     | 1       | 2      | 2                                    |
| 5 | 2     | 1       | 1      | 2                                    |
| 7 | 1     | 0       | 1      | 1                                    |
| 8 | 0     | 0       | 0      | 0                                    |

 */