[編程題] 基礎:如何使用大頂堆和小頂堆找topN


[編程題] 基礎:如何使用大頂堆和小頂堆找topN

需求

(1)我們如何從一個鏈表或者數組中,找到第k大的數,或者前k大的數。使用小頂堆。(輸出是從小到大排列的前K大的數)

(2)我們如何從一個鏈表或者數組中,找到第k小的數,或者前k小的數(輸出的堆是堆頂最大,其他不是序列順序),使用大頂堆

小頂堆

找到數組中第K大的元素

方法:需要找第K大,使用小頂堆。

Java代碼:

package Demo11_堆;

import java.util.PriorityQueue;

/**
 * @author jiyongjia
 * @create 2020/7/26 - 11:27
 * @descp:
 */
public class P1_小頂堆選出前K大 {
    //默認是小頂堆
    static int k=4;
    static PriorityQueue<Integer> queue;
    public static void main(String[] args) {
        queue = new PriorityQueue<Integer>(k);
        int[] arr = {1,3,5,2,6};
        //把數組元素放入到堆中
        for (int num:arr){
            P1_小頂堆選出前K大.add(num);
        }

    }

    //要求選出前k大的數
   public static void add(int val){
        if(queue.size()<k){
            queue.offer(val);
            //小頂堆的堆頂放的是已存在堆中的最下的數,如果有val比其最小的堆頂值大,說明堆中不是前k大的數,調整堆。
        }else if(queue.size()>=k && queue.peek()<val){
            queue.poll();
            queue.offer(val);
        }
       System.out.println("數組中第"+k+"大:"+queue.peek());  //數組中第4大:2
       System.out.println("堆:"+queue);   //堆:[2, 3, 5, 6]
    }
}

輸出:第4大的元素是2,堆中的i情況是2 3 5 6

image-20200726121613963

大頂堆

找到數組中第K小的元素

方法:需要找第K小,使用大頂堆。

注:要構造大頂堆的時候,是需要構造方法傳入comparator比較器,compare方法的參數o2-o1表示大頂堆。o1-o2返回表示小頂堆,小頂堆也是默認的,可以無comparator。

Java代碼:

package Demo11_堆;

import java.util.Comparator;
import java.util.Iterator;
import java.util.PriorityQueue;

/**
 * @author jiyongjia
 * @create 2020/7/26 - 11:54
 * @descp:
 */
public class P2_大頂堆選出前K小 {
    static PriorityQueue<Integer> queue;
    static int k = 3;
    public static void main(String[] args) {
        queue = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;  //小頂堆o1-o2,大頂堆o2-o1;
            }
        });

        int[] arr = {1,2,3,4,5,6,7,8};
        //把數組元素放入到堆中
        for (int num:arr){
            P2_大頂堆選出前K小.add(num);
        }

    }

    //要求選出前k小的數
    public static void add(int val){
        if(queue.size()<k){
            queue.offer(val);
            //大頂堆,堆頂放的是已存在堆中的最大的元素,如果存在val比堆中存在的最大元素小,說明堆中保存的不是前k小,去除堆頂,放入val
        }else if(queue.size()>=k && queue.peek()>val){
            queue.poll();
            queue.offer(val);
        }
        System.out.println("第k小的元素:"+queue.peek());
        System.out.println("堆中元素:"+queue);

    }
}

輸出:

image-20200726122033811


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM