剑指offer27--查找数组中最小的k个数

来源:互联网 发布:倒班表软件 编辑:程序博客网 时间:2024/06/03 17:43
题目: 输入n个整数,找出其中最小的k个数。

例如输入4 、5 、1、6、2、7、3 、8 这8 个数字,则最小的4 个数字是1 、2、3 、4

大神使用了两种方法,第一种我看了半天才勉强看懂的,然后自己指实现了一个方法,没能实现成功,关键是方法太巧妙了,不好想到。

package 剑指offer;/*题目: 输入n个整数,找出其中最小的k个数。例如输入4 、5 、1、6、2、7、3 、8 这8 个数字,则最小的4 个数字是1 、2、3 、4*//*可以基于Partition函数来解决这个问题。如果基于数组的第k个数字来调整,使得比第k个数字小的所有数字都位于数组的左边, *比第k个数字大的所有数字都位于数组的右边。这样调整之后,位于数组中左边的k个数字就是最小的k 个数字(这k个数字不一定 *是排序的。*//** * 题目: 输入n个整数,找出其中最小的k个数。 * 【第一种解法】 */public class Test30{public static void getLeastNumbers(int[] input, int[] output) {    if (input == null || output == null || output.length <= 0 || input.length < output.length) {        throw new IllegalArgumentException("Invalid args");    }    int start = 0;    int end = input.length - 1;    int index = partition(input, start, end);        // 根据Output的长度来确定目标长度    int target = output.length - 1;    while (index != target) {        if (index < target) {            start = index + 1;        } else {            end = index - 1;        }                // 一般不会正好的,所以向左向右逐个调整        index = partition(input, start, end);    }    System.arraycopy(input, 0, output, 0, output.length);}public static void getLeastNumbers1(int[] input, int[] output){//判断if (input == null || output == null || output.length <= 0 || input.length < output.length) {        throw new IllegalArgumentException("Invalid args");    }// 确定需要查找的数据的个数kint k = output.length;// 找到第k最小数的具体数值是多少(没办法还是要遍历,这样就没有大神的方法好了)}/** * 分区算法 * * @param input 输入数组 * @param start 开始下标 * @param end   结束下标 * @return 分区位置 */private static int partition(int[] input, int start, int end) {// 因为不知道排在 k+1 位置的元素是哪个元素,所以先选取第一个元素为分解元素    int tmp = input[start];    // 下面是分界的过程    while (start < end) {        while (start < end && input[end] >= tmp) {            end--;        }        // 因为上面end--了,所以将input[end]的值传给input[start]来处理        input[start] = input[end];        while (start < end && input[start] <= tmp) {            start++;        }        // 和上面一样也是因为start++了,再次交换而已        input[end] = input[start];    }        // 此时input[start]的值已经传出去了,所以将tmp放到这正好了    input[start] = tmp;        // 将这个位置坐标返回    return start;}private static int partition1(int[] input, int number) {// 数据的交换函数初见成效    int start = 0;    int end = input.length - 1;    while (start <= end) {    if(input[start] > number && input[end] < number){    int temp = input[start];    input[start] = input[end];    input[end] = temp;    }    if(input[start] <= number){    start++;    }    if(input[end] >= number){    end--;    }    }    return start;}public static void main(String[] args) {    System.out.println("第一种解法:");    int[] data = {4, 5, 1, 6, 2, 7, 3, 8};    int[] output = new int[4];    getLeastNumbers(data, output);    for (int i : output) {        System.out.print(i + " ");    }                System.out.println();        int[] data2 = {4, 5, 1, 6, 2, 7, 2, 8};        partition1(data2, 5);        for (int i : data2) {            System.out.print(i + " ");        }        System.out.println(); }}

坚持坚持再坚持

1 0
原创粉丝点击