29.最小的K个数

题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

题目解答

方法一:

import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> res=new ArrayList<>();
        if(input==null || k<1 || k>input.length){
            return res;
        }
        Arrays.sort(input);
        for(int i=0;i<k;i++){
            res.add(input[i]);
        }
        return res;
    }
}

方法二:Partition

快排:每一次划分就会有一个数字位于以数组从小到达排列的的最终位置。

位于index左边的数字都小于index对应的值,右边都大于index指向的值;

当index > k-1时,表示k个最小数字一定在index的左边,此时,只需要对index的左边进行划分即可;

当index < k-1时,说明index及index左边数字还没能满足k个数字,需要继续对k右边进行划分

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> res=new ArrayList<>();
        if(input==null || k<1 || k>input.length){
            return res;
        }
        int start=0,end=input.length-1;
        int index=partition(input,start,end);
        while(index!=k-1){
            if(index>k-1){
                end=index-1;
                index=partition(input,start,end);
            }else{
                start=index+1;
                index=partition(input,start,end);
            }
        }
        for(int i=0;i<k;i++){
            res.add(input[i]);
        }
        return res;
    }
    
    private int partition(int[] input,int lo,int hi){
        int pivot=(int)(lo+Math.random()*(hi-lo+1));
        int small=lo-1;
        swap(input,pivot,hi);
        for(int i=lo;i<hi;i++){
            if(input[i]<input[hi]){
                small++;
                if(i>small){
                    swap(input,small,i);
                }
            }
        }
        small++;
        swap(input,small,hi);
        return small;
    }
    
    private void swap(int[] input,int i,int j){
        int temp=input[i];
        input[i]=input[j];
        input[j]=temp;
    }
}

 

方法三:最大堆

import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.Comparator;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        
        ArrayList<Integer> res=new ArrayList<>();
        int length=input.length;
        if(k>length || k==0){
            return res;
        }
        
        //优先队列实现最大堆(个数有k个)
        PriorityQueue<Integer> maxHeap=new PriorityQueue<>(k,new Comparator<Integer>(){
            @Override
            public int compare(Integer o1,Integer o2){
                return o2.compareTo(o1);
            }
        });
        
        //最大堆的堆顶>新数,用新数替代掉堆顶
        for(int i=0;i<length;i++){
            if(maxHeap.size()!=k){
                maxHeap.offer(input[i]);
            }else if(maxHeap.peek()>input[i]){
                temp=maxHeap.poll();
                maxHeap.offer(input[i]);
            }
        }
        
        for(Integer integer:maxHeap){
            res.add(integer);
        }
        
        return res;
    }
}

compareTo方法:指定数如果大于参数的话那么则返回1

如果返回值是正数的话,让第二个参数在前面

如果返回值是负数的话,让第一个参数在前面

如果o2大于o1返回1,就让o2在前面,就是最大堆

// 默认实现了一个最小堆。

Queue<Integer> priorityQueue = new PriorityQueue<>();

posted @ 2019-01-03 21:04  chan_ai_chao  阅读(135)  评论(0)    收藏  举报