軟體工程師職涯升級計畫啟動!立即預約職涯諮詢、履歷健檢或模擬面試👈,為您的加薪做好準備!
這裡我們來實際模擬一段面試實戰對話,讓你看看整個流程會怎麼進行。
🤵 面試官說明題目:
給你一個整數陣列
時間複雜度須優於 O(n log n)。nums
和一個整數k
,請你回傳其中出現頻率最高的 k 個元素。
👨💻 面試者第一步:確認理解與釐清問題
我會先回應:「如果我理解正確,我需要找出陣列中最常出現的前 k 個數字,並回傳它們的值。請問有沒有可能有多個數字出現次數一樣?如果有,回傳任意 k 個都可以嗎?」
👨🏫 面試官回覆:
是的,有可能出現頻率一樣的情況,回傳任意 k 個都可以。
💡 思路發想與討論
我會先 verbalize 我的思路:
「我打算分兩步驟來解這題:
- 使用
Map
計算每個數字的出現次數 - 使用最小堆(Min Heap)來維持目前出現次數最多的 k 個元素。
因為堆可以保證插入與刪除的操作都是 O(log k),整體時間複雜度為 O(n log k),符合題目要求。」
💬 思路補充與選項比較
「另外一種方式是用 Bucket Sort,我可以用出現次數作為 index 建一個 bucket array,最後從尾巴往前數 k 個結果。不過這方式空間開銷較大,且實作較繁瑣,我會先實作 heap 解法。」
🔧 程式碼實作(JavaScript 範例)
javascript
複製編輯function topKFrequent(nums, k) {
const freqMap = new Map();
// 統計每個數字出現的次數
for (let num of nums) {
freqMap.set(num, (freqMap.get(num) || 0) + 1);
}
// 使用最小堆(這裡用陣列模擬,實際面試可說明 Heap 結構)
const heap = [];
for (let [num, freq] of freqMap.entries()) {
heap.push([freq, num]);
heap.sort((a, b) => a[0] - b[0]); // 最小堆,根據頻率排序
if (heap.length > k) {
heap.shift(); // 移除最小的
}
}
// 回傳 top k 項的元素值
return heap.map(([_, num]) => num);
}
🧪 測試案例驗證
javascript
複製編輯console.log(topKFrequent([1,1,1,2,2,3], 2)); // 輸出 [1,2]
console.log(topKFrequent([1], 1)); // 輸出 [1]
📊 複雜度分析
- 時間複雜度:
- 建立頻率表:O(n)
- 維護最小堆:O(n log k)
- 總共:O(n log k)
- 空間複雜度:
- Map 與 Heap 使用了額外空間:O(n)
🗣 模擬講解與溝通技巧
面試時講解重點:
「我選擇使用最小堆維持 top k 項。每次將新項目放入堆中,如果超出 k 個,我就移除出現頻率最少的。這樣可以確保最後留下的就是出現頻率最高的 k 個數字。」
萬一堆實作卡住了,你可以說:
「實作細節上我可以使用
PriorityQueue
或內建堆結構,這裡用 array 簡化模擬,重點是思路與操作順序。」
✅ 模擬面試總結
這題涵蓋了常見技巧:
- 哈希表記錄頻率
- 堆維護排序條件
- 時間複雜度優化
也是很多大公司(如 Google、Amazon、Meta)非常愛考的題型。練熟這類問題,面試過關的機率將大幅提升!
📌 想看更多 LeetCode 模擬面試題目與解法?
💬 歡迎留言告訴我你想練哪一類型題目(Array、Graph、String、Dynamic Programming)!