国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

聊聊TopK 算法的多種實現

開發 前端
TopK,即求數組的最小(或最大)的 k 個數,且不要求這些數要排序返回。

我是前端西瓜哥,今天來整下 TopK 算法。

TopK,即求數組的最小(或最大)的 k 個數,且不要求這些數要排序返回。

這是一個非常經典的面試題。解法也是相當的多,能較好考察面試者的數據結構與算法基礎。

求最小和最大的思路是一樣的,我們假設要求的是最小的 k 個數。

對應的 LeetCode 題目地址有兩個:

  • 《劍指 Offer(第 2 版)》第 40 題:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/
  • 《程序員面試經典(第 6 版)》17.14 題:https://leetcode-cn.com/problems/smallest-k-lcci/

排序

最簡單的方式是全排序,即對數組的所有元素都進行升序排序,然后取前面的 k 個數。通常都會用編程語言自帶的排序 API,正確性有所保證。

function getLeastNumbers(arr: number[], k: number): number[] {
return arr.sort((a, b) => a - b).slice(0, k);
};

實際開發中如果有這個需求,且數據量不大,用自帶的排序方法是最穩妥的。

因為排序方法底層通常是快排這些時間復雜度優秀的排序算法,所以全排序的時間復雜度是 O(n*log(n)。

在全排序的基礎上,其實可以做個優化,做 局部排序。有些算法(冒泡和選擇排序)的排序過程中,第 i 次迭代,都會使得第 i 個元素置于最終排好序后所在的位置。

這里我們看看魔改選擇排序的實現:

function getLeastNumbers(arr: number[], k: number): number[] {
let min: number;
let minIdx: number;
for (let i = 0; i < k; i++) { // 這里迭代了 k
min = arr[i];
minIdx = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < min) {
min = arr[j];
minIdx = j;
}
}
[arr[i], arr[minIdx]] = [arr[minIdx], arr[i]]; // 交換
}
return arr.slice(0, k);
};

只要我們將原來的 n 次迭代改為 k 次迭代,就能獲得一個只是前 k 個數組元素做了排序的數組。

局部排序在原來時間復雜度為 O(n^2) 的排序算法的基礎上,優化為了 O(k*n)。

當 k 很小時,局部排序的效率要比全排序的高。

快排思想

快速排序的核心是 分治 和 分區。

限于篇幅,具體的快排原理和實現可以看我的這篇文章:經典快速排序實現

簡單來說,快排的實現是,每次取一個基準值 pivot,將小于等于 pivot 的放到左區間,大于的放到右區間。然后針對這兩個區間繼續同樣操作,直到區間大小小于等于 1 為止,是自上而下的遞歸。

原來快排對兩個區間都要進行遞歸,現在改造為選擇性地遞歸。

每一次分區(partition)后:

  • 如果 pivot 所在的位置小于 k,遞歸就可以結束了,此時數組的前 k 個數組元素就是最小的 k 個元素;
  • 如果 pivot 所在的位置在 k 的左側,說明 pivot 的左區間可以不用排序了,小于等于 pivot 的值都在左側。然后對右區間進行遞歸;
  • 如果 pivot 所在的位置在 k 的右側,則 pivot 的右區間不用考慮了,需要對左區間遞歸。

這里有一個非常重要的點:每次分區分后 pivot 所在索引的值就是整個數組排過序后應該為的值。 這是我們可以不管其中一個區間的原因。

function getLeastNumbers(arr: number[], k: number): number[] {
partition(arr, 0, arr.length - 1, k);
return arr.slice(0, k);
};

function partition(arr: number[], lo: number, hi: number, k: number) {
if (lo >= hi) return;
const pivot = arr[hi]; // 這里可以改為隨機選擇 pivot
let i = lo;
for (let j = lo; j < hi; j++) {
if (arr[j] <= pivot) {
swap(arr, i, j);
i++;
}
}
swap(arr, i, hi);

// 原本的快排的 partition 的最后是這兩行,現在改為現在的下面這五行
// partition(arr, i + 1, hi, k);
// partition(arr, lo, i - 1, k);
if (i < k) {
partition(arr, i + 1, hi, k);
} else if (i > k) {
partition(arr, lo, i - 1, k);
}
}

function swap(arr: number[], i: number, j: number) {
let tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}

平均時間復雜度是 O(n),最壞時間復雜度是 O(n^2)。不管怎樣總體上都比快排效率高,除非極端情況。

大頂堆

大頂堆是個完全二叉樹,特點是:任何一個節點的值都大于等于子樹任意一個節點的值。

我們創建一個大小為 k 的大頂堆。先放入 k 個元素。后面想放入新元素時,先和堆頂元素(堆的最大值)對比。如果小于堆的最大元素,說明這個堆頂元素不合格,不可能為 TopK 的一員,將其出堆,然后讓新元素入堆;否則新元素不入堆。

一直這樣操作直到遍歷完整個數組。最后這個堆就是我們要的 TopK。

JavaScript 沒有內置堆或優先隊列這些數據結構,就暫且不實現了。

入堆的時間復雜度是 O(log k),要入堆 n 次,所以總的時間復雜度是 O(n*log k)。

如果你需要動態維護 TopK,比如網站的每日排行榜,用大頂堆方案會更合適。

結尾

總的來說,快排思想的方案時間復雜度最低,大頂堆適合需要動態維護 TopK 的情況,而全排序則適合寫業務代碼且數據量不大的時候。

責任編輯:姜華 來源: 今日頭條
相關推薦

2022-04-08 08:27:08

分布式鎖系統

2022-06-17 07:49:14

緩存LRU

2020-02-19 19:18:02

緩存查詢速度淘汰算法

2017-02-09 16:16:24

Java負載均衡算法

2019-12-11 10:50:06

JS圖片前端

2010-07-22 12:19:07

2022-10-08 00:07:00

JSV8調用棧

2024-12-23 15:05:29

2022-09-30 00:03:03

JS斷點線程

2018-05-28 15:33:09

無監督學習算法Python

2022-11-10 07:49:09

hash算法代碼

2022-06-28 15:13:12

Vuediff 算法

2023-11-28 09:19:12

2023-05-30 07:58:01

谷歌搜索算法

2021-12-14 10:54:31

TopK面試排序法

2024-05-31 09:31:00

2021-07-14 14:05:24

Fragment項目結構

2021-09-30 09:58:14

路徑總和二叉樹

2021-11-12 09:30:46

滑動窗口算法

2017-01-16 14:13:37

分布式數據庫
點贊
收藏

51CTO技術棧公眾號

视频在线观看免费高清| 91精品成人| 欧美成人免费播放| 最新日韩在线| 日韩福利视频在线| 色偷偷免费视频| 少女频道在线观看高清| 国产精品无码久久久久| 久久国产乱子精品免费女| 欧美在线视频你懂得| 西西人体一区二区| 在线看女人毛片| 7777kkk亚洲综合欧美网站| 欧美一级网站| 久久人人爽人人爽人人片亚洲| 电影午夜精品一区二区三区| 最新视频 - x88av| av在线免费一区| 精品一区毛片| 国产欧美一区二区三区鸳鸯浴 | 中日韩av电影| 色av吧综合网| 亚洲欧洲在线一区| 亚洲免费视频一区二区三区| 日韩av密桃| 国产精品久久久久国产精品日日| 亚洲欧美日韩久久久久久| 国产66精品久久久久999小说| 少妇高潮喷水久久久久久久久久| 美女免费免费看网站| 亚洲天堂av资源在线观看| 中文字幕中文字幕中文字幕亚洲无线| 中文字幕久热精品在线视频| 国产a级片免费观看| 免费日韩一区二区| 超碰精品一区二区三区乱码| 国产对白在线| 成人在线观看黄| 日韩av高清| 日韩欧中文字幕| 国产一区二区不卡| 久久亚洲电影| 日韩不卡一区二区三区| 国产精品久久久久影视| 欧美色老头old∨ideo| 一区二区日韩| 亚洲先锋成人| 一区二区久久| 日本一区二区三级电影在线观看| 国产电影精品久久禁18| 美女视频网站黄色亚洲| 一区二区三区四区日韩| 国产精品一区一区三区| 免播放器亚洲| www.av91| 成人信息集中地欧美| 日本一区二区在线视频| 黄色一级视频在线播放| 久久久久久青草| 国产日韩免费| 欧美一区二区三区久久精品茉莉花| 亚洲国产欧美久久| 在线看黄网站| 国产精品欧美极品| 水蜜桃色314在线观看| 亚洲毛片av| 国产欧美日韩91| 欧洲亚洲视频| 欧美激情xxxx性bbbb| 成人在线黄色电影| 国产精欧美一区二区三区| 人人鲁人人莫人人爱精品| 在线不卡的av| 99精品国产高清一区二区| 精品一区二区三区中文字幕在线 | 视频一区二区三区入口| 92裸体在线视频网站| 大型av综合网站| 欧美一级片在线播放| 一区二区免费| 日韩免费在线看| 一区二区三区在线电影| 粉嫩高清一区二区三区精品视频| 日韩伦理一区| 国产伦精品一区| 国产欧美高清| 欧美 日韩 国产精品| 久久精品亚洲精品国产欧美kt∨| mm131亚洲精品| 午夜影院在线观看欧美| 国产精品爽黄69天堂a| 欧美日韩一区二区三区四区不卡| 97精品免费视频| 亚洲色图欧美| 日本免费在线视频观看| www.色综合.com| 日韩a在线看| 日韩精品电影网| 先锋影音国产精品| 乱色588欧美| 国产美女视频一区二区| 国产97在线播放| 99精品国产在热久久| 久久手机在线视频| 亚洲国产色一区| 亚洲国产精品久久久久婷婷老年| 国产很黄免费观看久久| 女人黄色片免费| 亚洲精品videossex少妇| 国模吧精品视频| 国产一区一区三区| 午夜成人免费电影| 国产精品一区二区三区av | 欧美亚洲另类久久综合| 国产精品理论在线观看| 蜜臀av国内免费精品久久久夜夜| 国产精品日日摸夜夜添夜夜av| 狠狠v欧美v日韩v亚洲ⅴ| 亚洲成人套图| 日韩美女毛茸茸| 91热门视频在线观看| 成年人黄视频在线观看| 91视频免费在线| 亚洲天堂网中文字| 5月婷婷6月丁香| 一本久道久久久| 飘雪影院手机免费高清版在线观看| 日韩视频免费大全中文字幕| 激情国产一区二区| 久草在线视频福利| 久久精品二区| 欧美区视频在线观看| 98精品视频| 在线观看h视频| 久久国产精品久久| 久久激情视频久久| 91视频免费在线观看| av大片在线观看| 91视视频在线直接观看在线看网页在线看 | 国产精品视频精品视频| 成人av影院在线| 99tv成人影院| 免费h片在线观看| 热久久免费视频精品| 中文字幕一区二区三区乱码在线 | 日韩专区中文字幕一区二区| 麻豆tv入口在线看| 美女三级99| 日韩在线视频网| 国产色产综合产在线视频| av日韩在线播放| 免费av片在线观看一道本| 国产精品久久久久久久久久直播| 精品91自产拍在线观看一区| 成人美女在线观看| 中文字幕在线高清| 一区二区三区精品99久久| 久久久不卡影院| 视频一区视频二区中文字幕| 日韩福利一区| 中文字幕一区免费| 亚洲妇女成熟| 一区二区三区视频免费在线观看| 国产鲁鲁视频在线观看特色| 都市激情久久久久久久久久久| 日韩欧美国产麻豆| 中文字幕 久热精品 视频在线| 成人黄色av| 在线中文字幕播放| 羞羞网站免费观看| 亚洲图片都市激情| 2021国产精品视频| 亚洲欧美一区二区三区久久| 亚洲精品久久嫩草网站秘色| 在线观看一区| 欧美激情影院| 欧美超级免费视 在线| 欧美日韩国产黄| 久久综合久久综合久久综合| 亚洲激情自拍| 国产探花在线精品| 日韩大陆av| 免费一级欧美在线观看视频| h视频在线免费| 国产69精品久久久久孕妇| 国产高清av在线播放| 一区二区精品视频| 噜噜噜噜噜久久久久久91| 成人黄色大片在线免费观看| 91精品国产乱码久久久久久久久 | 麻豆av免费在线| 日韩欧美视频免费在线观看| japanese在线播放| 亚洲第一在线综合网站| 国产性天天综合网| 91香蕉视频在线| 国产精品进线69影院| 亚洲人妖av一区二区| 国产精品国模大尺度视频| 亚洲一区自拍偷拍|