面试题30.最小的K个数

来源:互联网 发布:贝佳斯白泥怎么样知乎 编辑:程序博客网 时间:2024/06/05 04:59

面试题30.最小的K个数

题目描述

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

思路1:

排序,然后取出前k个数字。这种方法的时间复杂度是O(nlogn)

思路2:

利用Partition算法,首先在数组中随机选择一个数字,然后把比它小的数字移到它的左边,把比它大的数字移到右边。全部移动完后:

  • 如果这个数字刚好处于第k个位置,那么它就是第k个数。
  • 如果这个数字在第k个位置的右边,说明第k个数在它左边,继续对左边查找
  • 如果这个数字在第k个位置的左边,说木第k个数在它右边,继续对右边查找

思路3:

针对海量数据,可以使用堆排序的方法。

构建一个大顶堆,用k个数字初始化堆。然后对于后面的数字,与堆顶比较

  • 如果小于堆顶,则与堆顶替换,向下调整堆。
  • 反之,这个数肯定不是最小的k个数,跳过这个数

思路4:
利用java的TreeMap来实现,统计数字出现的次数,然后从小到大找到第k个数。

下面是思路1和思路4的代码

import java.util.*;public class Solution {    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {        ArrayList<Integer> arr = new ArrayList<>();        if(k > input.length || k < 1) {            return arr;        }        // 解法1 排序 然后取前k个 O(nlogn)        /*Arrays.sort(input);        for(int i = 0; i < k; i++) {            arr.add(input[i]);        }*/        // 解法4 使用红黑树 增删改查O(logk)        TreeMap<Integer, Integer> treeMap = new TreeMap<>();        for(Integer i : input) {            if(treeMap.keySet().contains(i)) {                treeMap.put(i, treeMap.get(i) + 1);            }else {                treeMap.put(i, 1);              }                    }        for(Integer i : treeMap.keySet()) {                     int n = treeMap.get(i);            for(int j = 0; j < n; j++) {                arr.add(i);                k--;                if(k <= 0) return arr;            }        }        return arr;            }}

这里写图片描述

原创粉丝点击