Find X-Sum of All K-Long Subarrays I

easy sliding window hash table frequency count

Problem

The x-sum of an array: count every element's occurrences, keep only the x most frequent elements (if two elements occur the same number of times, the one with the bigger value wins), then sum the kept occurrences. If an array has fewer than x distinct values, its x-sum is just the sum of the whole array.

Given nums, k and x, return an array answer of length n − k + 1 where answer[i] is the x-sum of the window nums[i..i + k − 1].

Inputnums = [1,1,2,2,3,4,2,3], k = 6, x = 2
Output[6, 10, 12]
Window [1,1,2,2,3,4]: keep 1 (×2) and 2 (×2) → 1+1+2+2 = 6. Window [1,2,2,3,4,2]: keep 2 (×3) and 4 (×1, beats 1 and 3 by value) → 2+2+2+4 = 10. Window [2,2,3,4,2,3]: keep 2 (×3) and 3 (×2) → 2+2+2+3+3 = 12.

def findXSum(nums, k, x):
    n = len(nums)
    ans = []
    for i in range(n - k + 1):
        window = nums[i:i + k]
        cnt = {}                          # value -> occurrences
        for v in window:
            cnt[v] = cnt.get(v, 0) + 1
        # sort by (count, value) descending; bigger value breaks ties
        items = sorted(cnt.items(), key=lambda p: (p[1], p[0]), reverse=True)
        s = 0
        for v, c in items[:x]:            # keep the top x distinct values
            s += v * c                    # add all their occurrences
        ans.append(s)
    return ans
function findXSum(nums, k, x) {
  const n = nums.length, ans = [];
  for (let i = 0; i <= n - k; i++) {
    const window = nums.slice(i, i + k);
    const cnt = new Map();                // value -> occurrences
    for (const v of window) cnt.set(v, (cnt.get(v) || 0) + 1);
    // sort by count desc, then value desc to break ties
    const items = [...cnt.entries()].sort(
      (a, b) => b[1] - a[1] || b[0] - a[0]);
    let s = 0;
    for (const [v, c] of items.slice(0, x)) s += v * c;
    ans.push(s);
  }
  return ans;
}
int[] findXSum(int[] nums, int k, int x) {
    int n = nums.length;
    int[] ans = new int[n - k + 1];
    for (int i = 0; i <= n - k; i++) {
        Map<Integer, Integer> cnt = new HashMap<>();
        for (int j = i; j < i + k; j++)
            cnt.merge(nums[j], 1, Integer::sum);
        // sort by count desc, then value desc to break ties
        List<int[]> items = new ArrayList<>();
        for (var e : cnt.entrySet())
            items.add(new int[]{e.getKey(), e.getValue()});
        items.sort((a, b) -> b[1] != a[1] ? b[1] - a[1] : b[0] - a[0]);
        int s = 0;
        for (int t = 0; t < x && t < items.size(); t++)
            s += items.get(t)[0] * items.get(t)[1];
        ans[i] = s;
    }
    return ans;
}
vector<int> findXSum(vector<int>& nums, int k, int x) {
    int n = nums.size();
    vector<int> ans;
    for (int i = 0; i <= n - k; i++) {
        map<int, int> cnt;                 // value -> occurrences
        for (int j = i; j < i + k; j++) cnt[nums[j]]++;
        vector<pair<int,int>> items(cnt.begin(), cnt.end());
        // sort by count desc, then value desc to break ties
        sort(items.begin(), items.end(), [](auto& a, auto& b){
            return a.second != b.second ? a.second > b.second
                                        : a.first > b.first; });
        int s = 0;
        for (int t = 0; t < x && t < (int)items.size(); t++)
            s += items[t].first * items[t].second;
        ans.push_back(s);
    }
    return ans;
}
Time: O(n · k log k) Space: O(k)