Bootstrap

快速选择算法


在这里插入图片描述

1.二叉堆

思路:将节点一个一个的插入二叉堆(优先队列),当堆中元素多于k个时,删除堆顶元素。每个节点都过一遍之后,再取堆顶元素。
注意java中的优先队列默认是小顶堆,如果找的是第k个最大元素,则应该是把小的数字删掉留下大的,所以应该是使用小顶堆
如果是找第k个最小的元素,则应该是把大的删掉,则应该用的是大顶堆
java中使用大顶堆、小顶堆的代码

小顶堆

PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a,b)->a-b);
//括号里是重写比较器的lambda表达式,k是初始化大小
//小顶堆可以省略

大顶堆

PriorityQueue<Integer> minHeap = new PriorityQueue<>(k, (a,b)->b-a);
public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> que = new PriorityQueue<>();
        for (int num : nums) {
            que.offer(num);
            if (que.size()>k){
                que.poll();
            }
        }
        return que.peek();
    }

2.快速选择算法

2.1回顾快速排序算法

public void sort(int[] nums) {
        quickSort(nums, 0, nums.length - 1);
    }

    public void quickSort(int[] nums, int lo, int hi){
        if (hi<=lo) return;
        int partition = partition(nums, lo, hi);

        quickSort(nums,lo,partition-1);
        quickSort(nums,partition+1,hi);
    }

    public int partition(int[] nums, int lo, int hi){
        int pivot = nums[lo];
        int i = lo;
        int j = hi+1;
        while (true){
            while (nums[++i]<pivot){
                if (i==hi) break;
            }

            while (nums[--j]>pivot){
                if (j==lo) break;
            }

            if (i>=j) break;

            swap(nums,i,j);
        }
        swap(nums,lo,j);
        return j;
    }

    public void swap(int[] nums,int i,int j){
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }

2.2快速选择算法

public int findKthLargest(int[] nums, int k) {
        k = nums.length - k;
        int lo = 0, hi = nums.length - 1;
        while (lo<=hi){
            int partition = partition(nums, lo, hi);
            if (partition<k){
                lo = partition+1;
            }else if (partition>k){
                hi = partition - 1;
            }else {
                return nums[partition];
            }
        }
        return -1;
    }

总结

遇到题目优先选择二叉堆,快速排序算法熟记

;