347. Top K Frequent Elements - Bucket Sorting

Borris發表於2020-03-16

題目詳見:347. Top K Frequent Elements

PrioirtyQueue 的解法可以參考類似題 692 的解法:點這裡

下面介紹最優解:Bucket Sorting

解法一 Bucket Sorting

思路

一個長度為 n 的陣列,一個數字最低的頻率為0,最高的頻率為n。所以所有可能的頻率情況為n。我們可以用一個 長度為 n + 1 的list 陣列來記錄屬於不同頻率的所有數字。比如 list[2] = {3, 4} 代表頻率為 2 的數字有 3 和 4。

取前 k 個頻率最高的元素時,我們僅需從 list 的最後開始遍歷取數字,直到取滿 k 個數字為止。

程式碼
class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        List<Integer> res = new ArrayList<>();

        List<Integer>[] list = new ArrayList[nums.length + 1]; // Frequency array

        // 記錄每個數字的頻率
        for (int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        // 記錄相應頻率下的數字
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            int freq = entry.getValue();
            if (list[freq] == null) list[freq] = new ArrayList<>();
            list[freq].add(entry.getKey());
        }

        // 新增 k 個頻率最高的數字
        for (int i = nums.length; i >= 0 && res.size() < k; i--) {
            if (list[i] != null) res.addAll(list[i]);
        }

        return res;
    }
}
複雜度分析
  • 時間複雜度 O(n) – 第一個 for 迴圈 O(n), 第二個 for 迴圈 O(n), 第三個 for 迴圈 O(k).
  • 空間複雜度 O(n) – bucket 陣列儲存了所有 n 個數字的頻率
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章