學習筆記 | 詳解TopK 問題

詳解 TopK

01 TopK 問題

  • TopK 問題是在實際業務中經常出現的典型問題,例如微博的熱門排行就屬於 TopK 問題。
  • TopK 一般是要求在 N 個數的集合中找到最小或者最大的 K 個值,通常 N 都非常得大。TopK 可以通過排序的方式解決,但是時間複雜度較高,一般是 O(nk),這裏我們來看看更加高效的方法。
    在這裏插入圖片描述
  • 如下圖所示,首先取前 K 個元素建立一個大根堆,然後對剩下的 N-K 個元素進行遍歷,如果小於堆頂的元素,則替換掉堆頂元素,然後調整堆。當全部遍歷完成時,堆中的 K 個元素就是最小的 K 個值。
  • 這個算法的時間複雜度是 N*logK
  • 算法的優點是不用在內存中讀入全部的元素,能夠適用於非常大的數據集。

02 TopK 變種問題

  • TopK 變種的問題,就是從 N 個有序隊列中,找到最小或者最大的 K 個值。這個問題的不同點在於,是對多個數據集進行排序。由於初始的數據集是有序的,因此不需要遍歷完 N 個隊列中所有的元素。因此,解題思路是如何減少要遍歷的元素。
解題思路如下圖所示。

在這裏插入圖片描述

  1. 第一步先用 N 個隊列的隊頭元素,也就是每個隊列的最小元素,組成一個有 K 個元素的小根堆。方式同 TopK 中的方法。
  2. 第二步獲取堆頂值,也就是所有隊列中最小的一個元素。
  3. 第三步用這個堆頂元素所在隊列的下一個值放入堆頂,然後調整堆。
  4. 最後重複這個步驟直到獲取夠 K 個數。

這裏還可以有個小優化就是第三步往堆頂放入新值時,跟堆的最大值進行一下比較,如果已經大於堆中最大值,就可以提前終止循環了。這個算法的時間複雜度是 (N+K-1)*logK,注意這裏與隊列的長度無關。