剑指offer——最小的k个数

方法一:用partition来做,把之前求中位数的方法,类似用到这个题上,只是求的不是中位数,而是排序后的第k-1的位置,注意边界

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> al=new ArrayList<Integer>();
        if(input.length<k||k==0)
            return al;
        int s=0,e=input.length-1;
        int p=partition(input,s,e);
        while(p!=k-1){
            if(p<k-1){
                s=p+1;
                p=partition(input,s,e);
            }
            else{
                e=p-1;
                p=partition(input,s,e);
            }
        }
        for(int i=0;i<k;i++){
            al.add(input[i]);
        }
        return al;
    }
    public int partition(int[] arr,int start,int end){
        int p=end;
        int i=start-1,j=end;
        while(true){
            while(arr[++i]<arr[p]);
            while(j>0&&arr[--j]>arr[p]);
            if(i<j)
                swap(arr,i,j);
            else
                break;
        }
        swap(arr,i,p);
        return i;
    }
    public void swap(int[] arr,int i,int j){
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
}

方法二:利用TreeSet,它实现了红黑树的查找,它的查找、删除和插入操作时间复杂度都是O(logk),这个方法不用改变输入数组,适用于海量数据(内存有限时,可以分批次读入),但是时间会稍微长一点,上面那个方法大概17ms,这个方法大概26ms,代码如下

import java.util.ArrayList;
import java.util.TreeSet;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> a=new ArrayList<Integer>();
        if(k>input.length||k==0)
            return a;
        TreeSet<Integer> ti=new TreeSet<Integer>();
        for(int i=0;i<input.length;i++){
            if(ti.size()<k){
                ti.add(input[i]);
            }
            else{
                //注意TreeSet的几种用法
                if(ti.ceiling(input[i])!=null){
                    ti.pollLast();
                    ti.add(input[i]);
                }
                else;
            }
        }
        //注意addAll添加的是Collection
        a.addAll(ti);
        return a;
    }
    
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值