1. 程式人生 > >LeetCode:數組中的第K個最大元素【215】

LeetCode:數組中的第K個最大元素【215】

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】