LeetCode:數組中的第K個最大元素【215】
阿新 • • 發佈:2018-11-20
public off 9.png spa 葉子節點 子節點 最大的 比較 div
LeetCode:數組中的第K個最大元素【215】
題目描述
在未排序的數組中找到第 k 個最大的元素。請註意,你需要找的是數組排序後的第 k 個最大的元素,而不是第 k 個不同的元素。
示例 1:
輸入: [3,2,1,5,6,4] 和
k = 2
輸出: 5
示例 2:
輸入: [3,2,3,1,2,4,5,5,6] 和
k = 4
輸出: 4
說明:
你可以假設 k 總是有效的,且 1 ≤ k ≤ 數組的長度。
題目分析
我們主要來學習一個新的集合類型——優先隊列。優先隊列作用是保證每次取出的元素都是隊列中權值最小的。
這裏牽涉到了大小關系,元素大小的評判可以通過元素本身的自然順序 ,也可以通過構造時傳入的比較器。我們這裏是數組,比較數字大小即可,不需要比較器。
Java中PriorityQueue實現了Queue接口,不允許放入null
元素;其通過堆實現,具體說是通過完全二叉樹實現的小頂堆(任意一個非葉子節點的權值,都不大於其左右子節點的權值)。線程不安全。
既然是小頂堆那麽就是下圖這樣:
無論堆中有幾個元素,堆頂的元素一定是最小的,所以我們讓堆中僅保留K個元素,那麽處於堆頂的元素一定是第K大的(或者說是最小的)。我們始終維持堆的元素在K個,每當超過後,我們就POLL出去堆頂元素,那麽最後剩下的K個元素,就是整個數組中最大的K個元素。
比如我們取第三大元素,那麽我們的堆大小就恒定為3,每次 將入新元素,重新構造堆,最後的堆頂元素3,就是第3大元素。
關於PriorityQueue的進一步學習,可以參考這篇文章:
https://github.com/CarpenterLee/JCFInternals/blob/master/markdown/8-PriorityQueue.md
Java題解
class Solution { public int findKthLargest(int[] nums, int k) { PriorityQueue<Integer> queue = new PriorityQueue<>(); for(int num:nums) { queue.offer(num); if(queue.size()>k) queue.poll(); } return queue.peek(); } }
LeetCode:數組中的第K個最大元素【215】