剑指offer系列之二十八:最小的k个数

来源:互联网 发布:2016淘宝睡衣模特红人 编辑:程序博客网 时间:2024/05/05 19:33

题目描述

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

对于此题,我觉得使用Java实现的话(所有OJ的代码都是使用Java实现的),实在是没有什么难度,就是一个简单的Collections函数的调用嘛,然而就是这么简单的一题,我居然提交代码提交了三次才被AC,实在是郁闷啊。主要的原因在于对边界条件的处理不是很好,简单而言就是代码不够健壮。还是言归正传,说说这题的思路吧:由于是n个整数,我们完全可以使用Java API中的函数完成这一功能,首先把数组中的元素添加到list集合对象中,然后调用Collections.sort()函数,完成排序(这个过程的时间复杂度是O(nlogn),因为该函数的实现采用了快速排序算法),然后把list集合中除前k个数删掉,这样就返回了最小的k个数。

下面是基于这种思路代码实现(已被牛客AC):

package com.rhwayfun.offer;import java.util.ArrayList;import java.util.Collections;public class GetLeastKNumbers {    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {        ArrayList<Integer> list = new ArrayList<Integer>();        //注意边界条件的处理,很重要!        if(input == null || k <= 0 || input.length == 0 || k > input.length) return list;        for (int i = 0; i < input.length; i++) {            list.add(input[i]);        }        //排序        Collections.sort(list);        if(k >= input.length){            return list;        }        //移除后面的元素        while(list.size() > k){            list.remove(k);        }        return list;    }    public static void main(String[] args) {        int[] input = new int[]{4,5,1,6,2,7,3,8};        ArrayList<Integer> list = new GetLeastKNumbers().GetLeastNumbers_Solution(input, 8);        System.out.println(list);        System.out.println(0x8000000);    }}

下面介绍一种书上的第二种思路:创建一个用于保存最小k个数的容器,第一步是放入k个元素,第二步是比较容器中最大的数与当前数组遍历的那个数的大小,如果容器中最大的数比当前遍历的数大,就移除该数,并放入当前遍历的那个数。这样整个循环结束的时候,容器中就是最小的k个数了。下面是基于这种思路的实现算法:

public ArrayList<Integer> GetLeastNumbers_Solution2(int[] input, int k) {        ArrayList<Integer> list = new ArrayList<Integer>();        if(input == null || k <= 0 || input.length == 0 || k > input.length) return list;        //创建一TreeSet集合,因为TreeSet默认就是从小到大排序的        TreeSet<Integer> s = new TreeSet<Integer>();        for (int i = 0; i < input.length; i++) {            if(s.size() < k){                s.add(input[i]);            }else{                if(input[i] < s.last()){                    s.remove(s.last());                    s.add(input[i]);                }            }        }        //循环结束,s中已经保存了前k个最小的数,只需要迭代放入ArrayList中即可        Iterator<Integer> it = s.iterator();        while(it.hasNext()){            list.add(it.next());        }        return list;    }
0 0
原创粉丝点击