剑指offer-最小的k个数

题目描述

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

思路

O(n)时间算法,只有可以修改输入数组时可用。

可以基于 Partition 函数来解决这个问题。如果基于数组的第k个数字来调整,使得比第k个数字小的所有数字都位于数组的左边,比第 k 个数字大的所有数字都位于数组的右边。这样调整之后,位于数组中左边的 k 个数字就是最小的 k 个数字(这 k 个数字不一定是排序的)。

import java.util.ArrayList;

public class Test {

    public static void main(String[] args) {
        int[] a = { 4, 5, 1, 6, 2, 7, 3, 8};
        System.out.println(GetLeastNumbers_Solution(a, 8));
    }

    public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        if(input == null || input.length <= 0 || k > input.length || k <= 0)
            return list;
        int index = partition(input, 0, input.length - 1);
        while (index != k - 1) {
            if(index > k - 1)
                index = partition(input, 0, index - 1);
            else 
                index = partition(input, index + 1, input.length - 1);
        }
        for(int i=0; i<k; i++) {
            list.add(input[i]);
        }
        return list;
    }

    private static int partition(int[] input, int low, int high) {
        if(input == null || input.length <= 0 || low < 0 || high >= input.length || low > high )
            return 0;
        int key = input[low];
        while(low < high) {
            while(low < high && input[high] >= key)
                high --;
            input[low] = input[high];
            
            while(low < high && input[low] <= key)
                low ++;
            input[high] = input[low];
        }
        input[low] = key;
        return low;
    }
}
原文地址:https://www.cnblogs.com/zywu/p/5783245.html