题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
 
 
题目链接:
 
 
 
分析:
topN问题-大顶堆与小顶堆。
最小N个数,大顶堆。
最大N个数,小顶堆。
 
 
 
 
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        //特殊情况处理
        if(k==0||input.length==0||input.length<k){
            return new ArrayList<>();
        }
        //创建堆
        createHeap(input,k);
        //遍历k个数以外的数字
        for(int i = k;i < input.length;i++){
            downAdjust(input,i,k);
        }
        ArrayList<Integer> list = new ArrayList<>();
        for(int i=0;i<k;i++){
            list.add(input[i]);
        }
        return list;
    }
    //获取父节点
    public int getParent(int pos){
        return (pos - 1)/2;
    }
    //获取左节点
    public int getLeft(int pos){
        return pos*2+1;
    }
    //获取右节点
    public int getRight(int pos){
        return pos*2+2;
    }
    //两个节点交换位置
    public void swap(int[] arr,int i,int j){
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    //创建k大的堆
    public void createHeap(int[] arr,int k){
        for(int i=1;i<k;i++){
            upAdjust(arr,i);
        }
    }
    //向上调整堆
    public void upAdjust(int[] arr,int pos){
        while(getParent(pos)>=0 && arr[getParent(pos)]<arr[pos]){
            swap(arr,getParent(pos),pos);
            pos = getParent(pos);
        }
    }
    //向下调整堆
    public void downAdjust(int[] arr,int pos,int k){
        if(arr[0] <= arr[pos]){
            return;
        }
        swap(arr,0,pos);
        pos = 0;
        while(getLeft(pos)<k){
            int node = getLeft(pos);
            if(node + 1 < k &&arr[node + 1] > arr[node]){
                node++;
            }
            if(arr[node] > arr[pos]){
                swap(arr,node,pos);
                pos = node;
            }else{
                break;
            }
        }
    }
}

 

 
 
posted on 2020-06-08 02:38  MoonBeautiful  阅读(90)  评论(0编辑  收藏  举报