二刷
大根堆

import java.util.ArrayList;

public class Solution {

    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if (input == null || input.length == 0 || k > input.length || k == 0)
            return list;
        int[] heap =new int[k];
        for(int i=0;i<k;i++)
            heap[i] = input[i];

        buildMaxHeap(heap,k);
        for(int i=k;i<input.length;i++){
            if(input[i] < heap[0]){
                heap[0] = input[i];
                heapify(heap,k,0);
            }
        }

        for (int i = 0; i < heap.length; i++) {
            list.add(heap[i]);
        }
        return list;
    }

    public void buildMaxHeap(int[] heap, int len){
        for(int i = len/2-1;i>=0;i--){
            heapify(heap,len,i);
        }
    }

    public void heapify(int[] heap, int len, int k){
        int leftc = 2*k+1;
        int rightc = 2*k+2;
        int largest = k;
        // 这块别乱
        if(leftc<len && heap[leftc] > heap[largest]) largest = leftc;
        if(rightc<len && heap[rightc] > heap[largest]) largest = rightc;
        if(largest !=k) {
            swap(heap,k,largest);
            heapify(heap,len,largest);
        }
    }

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

一定先是j-- 后是i++;
否则 这行
while(i<j && nums[i] < nums[l] ) i++;
把等号去掉 不用在意顺序

import java.util.ArrayList;

public class Solution {
    int[] nums;
    int target = -1;
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        this.nums = input;
        partition(0,input.length-1,k-1);
        ArrayList<Integer> list = new ArrayList<Integer>();

        for(int i=0;i<input.length;i++){
            if(nums[i]<target) list.add(nums[i]);
        }
        for(int count = list.size();count<k;count++){
            list.add(target);
        }
        return list;

    }
    public void partition(int l, int r, int k){
        if(l>r) return ;
        int i=l;
        int j=r;
        while(i<j){
            while(i<j && nums[j] >= nums[l])  j--;
            while(i<j && nums[i] <= nums[l] ) i++;
            swap(i,j);
        }
        swap(i,l);
        if(i==k) target=nums[i];
        else if(i>k)  partition(l,i-1,k);
        else  partition(i+1,r,k);

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

NC88 最大k个 同理

1.快排做法
partition 每次确定一个数的位置

import java.util.ArrayList;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        if(k==0){return list;}
        int min_num = minK(input,0,input.length-1,k-1);
        int count = 0;
        for(int i = 0; i < input.length ;i++){
            if(input[i]<min_num){
                list.add(input[i]);
                count++;
            }
        }
        while(count<k){
            list.add(min_num);
            count++;
        }
        return list;
    }

    public int minK(int[] nums, int l, int r, int k){
        int random = l + (int) (Math.random() * ( r-l+1));
        int[] range = partition(nums, l, r, nums[random]);
        if(k<=range[1] && k>=range[0]){
            return nums[k];
        }
        else if(k<range[0]){
            return minK(nums,l,range[0]-1,k);
        }
        else{
            return minK(nums,range[1]+1,r,k);
        }
    }

    public int[] partition(int[] nums, int l, int r, int pivot){
        if(l==r){
            int[] range = {l, r};
            return range;
        }
        int less = l;
        int more = r;
        int cur = l;
        while(cur<= more){
            if(nums[cur]>pivot){
                swap(nums,cur,more);
                more--;
            }
            else if(nums[cur]<pivot){
                swap(nums,cur,less);
                less++;cur++;
            }
            else{
                cur++;
            }
        }
        int[] range = {less, more};
        return range;
    }
    public void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}
  1. 大根堆

完全二叉树 性质
heapify 调整堆化
buildMaxHeap 从最后一个节点的父节点开始调整

import java.util.ArrayList;
import java.util.*;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> list = new ArrayList<>();
        if (input == null || input.length == 0 || k > input.length || k == 0)
            return list;
        int[] arr = new int[k];
        //初始化数组
        for (int i = 0; i < k; i++)
            arr[i] = input[i];
        buildMaxHeap(arr, k);//构造大根堆
        for (int i = k; i < input.length; i++) {
            if (input[i] < arr[0]) {
                arr[0] = input[i];
                heapify(arr, k, 0);//将改变了根节点的二叉树继续调整为大根堆
            }
        }
        for (int i = 0; i < arr.length; i++) {
            list.add(arr[i]);
        }
        return list;
    }

    public void buildMaxHeap(int[] arr, int k){
        for(int i=k/2-1; i>=0; i--){
            heapify(arr,k,i);
        }
    }

    public void heapify(int[] arr, int length, int k ){
        int leftchild = 2*k + 1;
        int rightchild = 2*k + 2;
        int larget = k;
        if(leftchild<length && arr[larget]<arr[leftchild]){
            larget = leftchild;
        }
        if(rightchild<length && arr[larget]<arr[rightchild]){
            larget = rightchild;
        }
        if(larget != k){
            swap(arr,larget,k); // 需要调整被交换的节点
            heapify(arr, length, larget);
        }
    }

    public void swap(int[] arr, int a,int b){
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}