查找 TopK 問題

?從海量數(shù)字中尋找最大/小的 k 個,這類問題我們稱為 TopK 問題谱仪。

通常使用數(shù)據(jù)結(jié)構(gòu)-最大/小堆來解決

  • 求前 k 大玻熙,用最小堆,即堆頂元素為堆中最小值疯攒。
  • 求前 k 小嗦随,用最大堆,即堆頂元素為堆中最大值敬尺。

如前k大的值, 傳入列表 list=[12, 39, 3, 72, 56, 81, 15, 9, 103] 和 k=3, 輸出 [103, 81, 72]枚尼。
如前k小的值, 傳入列表 list=[12, 39, 3, 72, 56, 81, 15, 9, 103] 和 k=3, 輸出 [3, 9, 12]。

前K大值

思路:

迭代列表元素:

  • 1.先放入元素前 k 個建立一個最小堆砂吞;
  • 2.當前元素x若大于堆頂元素:移除堆頂元素并入隊x姑原;
  • 3.最后獲取 最小堆 中的值,即為 topK4Max呜舒。

JAVA參考代碼

public static int[] topK4Max(int[] nums, int k) {
?
    // 優(yōu)先隊列锭汛、從小到大 (默認也是自然排序)
    Queue<Integer> minHeap = new PriorityQueue<>(Comparator.naturalOrder());
    // 建立最小堆
    for (int i = 0, len = nums.length; i < len; i++) {
        if (minHeap.size() < k) {
            minHeap.offer(nums[i]); // 入隊
            continue;
        }
        if (nums[i] > minHeap.peek()) { // 取隊首元素比較,不移除
            minHeap.poll(); // 取隊首元素袭蝗,并移除
            minHeap.offer(nums[i]);
        }
    }
    // 遍歷隊列
    List<Integer> list = new ArrayList<>();
    Iterator<Integer> iterator = minHeap.iterator();
    while (iterator.hasNext()){
        list.add(iterator.next());
    }
    // 從大到小排序
    Collections.sort(list, (o1, o2) -> o1 < o2 ? 1 : o1 == o2 ? 0 : -1);
    // 轉(zhuǎn)換成數(shù)組
    return list.stream().mapToInt(Integer::valueOf).toArray();
?
}

前K小值

思路:

迭代列表元素:

  • 1.先放入元素前 k 個建立一個最大堆唤殴;
  • 2.當前元素x若小于堆頂元素:移除堆頂元素并入隊x;
  • 3.最后獲取 最大堆 中的值到腥,即為 topK4Min朵逝。

JAVA參考代碼

public static int[] topK4Min(int[] nums, int k) {
?
    // 優(yōu)先隊列、從大到小排序
    Queue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
    // 建立最大堆
    for (int i = 0, len = nums.length; i < len; i++) {
        if (maxHeap.size() < k) {
            maxHeap.offer(nums[i]); // 入隊
            continue;
        }
        if (nums[i] < maxHeap.peek()) { // 取隊首元素比較乡范,不移除
            maxHeap.poll(); // 取隊首元素配名,并移除
            maxHeap.offer(nums[i]);
        }
    }
    // 遍歷隊列
    List<Integer> list = new ArrayList<>();
    Iterator<Integer> iterator = maxHeap.iterator();
    while (iterator.hasNext()){
        list.add(iterator.next());
    }
    // 從小到大排序
    Collections.sort(list);
    // 轉(zhuǎn)換成數(shù)組
    return list.stream().mapToInt(Integer::valueOf).toArray();
    
}

測試代碼

public static void main(String[] args) {
    int[] nums = new int[]{12, 39, 3, 72, 56, 81, 15, 9, 103};
?
    int[] maxK = topK4Max(nums, 3);
    System.out.println(JSON.toJSONString(maxK));
?
    int[] minK = topK4Min(nums, 3);
    System.out.println(JSON.toJSONString(minK));
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末啤咽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子渠脉,更是在濱河造成了極大的恐慌宇整,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芋膘,死亡現(xiàn)場離奇詭異鳞青,居然都是意外死亡,警方通過查閱死者的電腦和手機为朋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門臂拓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人习寸,你說我怎么就攤上這事胶惰。” “怎么了霞溪?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵孵滞,是天一觀的道長。 經(jīng)常有香客問我威鹿,道長剃斧,這世上最難降的妖魔是什么轨香? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任忽你,我火速辦了婚禮,結(jié)果婚禮上臂容,老公的妹妹穿的比我還像新娘科雳。我一直安慰自己,他們只是感情好脓杉,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布糟秘。 她就那樣靜靜地躺著,像睡著了一般球散。 火紅的嫁衣襯著肌膚如雪尿赚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天蕉堰,我揣著相機與錄音凌净,去河邊找鬼。 笑死屋讶,一個胖子當著我的面吹牛冰寻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播皿渗,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼斩芭,長吁一口氣:“原來是場噩夢啊……” “哼轻腺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起划乖,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤贬养,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后迁筛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煤蚌,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年细卧,在試婚紗的時候發(fā)現(xiàn)自己被綠了尉桩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡贪庙,死狀恐怖蜘犁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情止邮,我是刑警寧澤这橙,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站导披,受9級特大地震影響屈扎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜撩匕,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一鹰晨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧止毕,春花似錦模蜡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谨朝,卻和暖如春卤妒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背字币。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工则披, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纬朝。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓收叶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親共苛。 傳聞我的和親對象是個殘疾皇子判没,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容