29最小的K个数

题目描述

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

思路分析

  • 快速选择——会超时…

基于数组的第k个数字来调整,使得比第k个数字小的所有数字都位于数组的左边,比第k个数字大的所有数字都位于数组的右边。调整之后,位于数组左边的k个数字就是最小的k个数字。

  • 大小为K的最小堆

构建一个大顶堆,维护到目前为止最小的k个数。将堆的大小设为k,遍历输入,当堆满并且堆顶元素大于当前元素时,用当前元素替换当前堆的顶部元素。
注意:PriorityQueue默认是小顶堆,需要通过传入自定义Comparator函数修改为大顶堆

  • 冒泡排序

从后往前冒泡排序,将最小的K个值上浮后就结束循环。

代码实现

//快速选择
public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {

    ArrayList<Integer> result = new ArrayList<>();
    if(input.length<k || k==0 || input.length==0 || input==null){
        return result;
    }

    //快排--超出运行时间
    int pivot = quickSort(input,0,input.length-1);
    while (pivot!=(k-1)){
        if(pivot>(k-1)){
            quickSort(input,0,pivot-1);
        }else{
            quickSort(input,pivot+1,input.length-1);
        }
    }
    for (int i = 0; i < k; i++) {
        result.add(input[i]);
    }
    return result;
    }
    
    public static int quickSort(int[] array, int low, int high) {
    int left = low, right = high;
    int temp = array[left];
    while (left < right) {
        while (left < right  && array[right] >= temp) {
            right--;
        }
        array[left] = array[right];
        while (left < right  && array[left] <= temp) {
            left++;
        }
        array[right] = array[left];
    }
    array[left]=temp;
    return left;
}

//最小堆
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> result = new ArrayList<>();
        if(input.length<k || k==0 || input.length==0 || input==null){
            return result;
        }
        
         PriorityQueue<Integer> bigHeap = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);//o2 - o1;
            }
        });
        for (int num:input){
            if(bigHeap.size()<k){
                bigHeap.add(num);
            }else {
                if(num<bigHeap.peek()){
                    bigHeap.poll();
                    bigHeap.add(num);
                }
            }
        }

        while (!bigHeap.isEmpty()){
            result.add(bigHeap.poll());
        }

        return result;
    }
}

//冒泡排序
for (int i = input.length-1; i >= input.length-1-k; i--) {
    for (int j = 0; j < i; j++) {
        if(input[j]>input[j+1]){
            int temp=input[j];
            input[j]=input[j+1];
            input[j+1]=temp;
        }
    }
}
 for (int i = 0; i < k; i++) {
    result.add(input[i]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值