美文网首页剑指 Offer Java版剑指offer
剑指Offer Java版 面试题40:最小的k个数

剑指Offer Java版 面试题40:最小的k个数

作者: 孙强Jimmy | 来源:发表于2019-07-27 18:07 被阅读4次

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

    练习地址

    https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf

    解法一:时间复杂度为O(n)的算法,只有当我们可以修改输入的数组时可用

    import java.util.ArrayList;
    
    public class Solution {
        public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
            ArrayList<Integer> result = new ArrayList<>();
            if (input == null || input.length == 0 || k <= 0 || k > input.length) {
                return result;
            }
            int start = 0, end = input.length - 1;
            int index = partition(input, start, end);
            while (index != k - 1) {
                if (index > k - 1) {
                    end = index - 1;
                } else {
                    start = index + 1;
                }
                index = partition(input, start, end);
            }
            for (int i = 0; i < k; i++) {
                result.add(input[i]);
            }
            return result;
        }
        
        // 基于《算法(第4版)》的快速排序算法代码
        private int partition(int[] a, int lo, int hi) {
            if (lo == hi) {
                return lo;
            }
            int i = lo, j = hi + 1;
            int v = a[lo];
            while (true) {
                while (a[++i] < v) {
                    if (i == hi) {
                        break;
                    }
                }
                while (v < a[--j]) {
                    if (j == lo) {
                        break;
                    }
                }
                if (i >= j) {
                    break;
                }
                exch(a, i, j);
            }
            exch(a, lo, j);
            return j;
        }
        
        private void exch(int[] a, int i, int j) {
            int t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }
    

    复杂度分析

    • 时间复杂度:O(n)。
    • 空间复杂度:O(1)。

    解法二:时间复杂度为O(nlogk)的算法,特别适合处理海量数据

    import java.util.ArrayList;
    import java.util.PriorityQueue;
    
    public class Solution {
        public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
            ArrayList<Integer> result = new ArrayList<>();
            if (input == null || input.length == 0 || k <= 0 || k > input.length) {
                return result;
            }
            PriorityQueue<Integer> queue = new PriorityQueue<>();
            for (int number : input) {
                queue.add(number);
            }
            for (int i = 0; i < k; i++) {
                result.add(queue.poll());
            }
            return result;
        }
    }
    

    复杂度分析

    • 时间复杂度:O(nlogk)。
    • 空间复杂度:O(n)。

    👉剑指Offer Java版目录
    👉剑指Offer Java版专题

    相关文章

      网友评论

        本文标题:剑指Offer Java版 面试题40:最小的k个数

        本文链接:https://www.haomeiwen.com/subject/nwgerctx.html