剑指Offer—— 最小的K个数

来源:互联网 发布:mac装windows虚拟机 编辑:程序博客网 时间:2024/05/23 11:47

题目描述

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


第一种方法是全排序,先把数组进行排序,排序后依次输出最小的4个,时间复杂度为nlogn。

第二种方法是的原理和快速排序有关,是通过快速排序的优化版解题目。快速排序是定义一个基点(一般是第一个数字),每次排序后会把数组中小于基点的放在前面,大于基点的放在后面。(具体的快速排序算法不说了)

如题目中的一个基点为4,第一次排序后:3, 2, 1, 4, 6, 7, 5, 8。如果我们需要的k和4的位置相等,就不用继续排序,因为4之前的都是小于4的。k比4所在的位置大时,只需要排序4之后的数字。k比4所在的位置小时,只需要排序4之前的数字。
(掌握快速排序应该对这个思路很了解,这个最糟糕的情况是nlogn)

public class Solution13 {    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {        ArrayList<Integer> list=new ArrayList<>();        if(input.length<k) return list;        quicksort(input,0,input.length-1,list,k);        for(int i=0;i<k;i++){            list.add(input[i]);        }        return list;    }    //类似快速排序    private void quicksort(int[] input, int s, int end, ArrayList<Integer> list,int k) {        if(s>end) return ;        if(s==end){            return ;        }        int temp=input[s];        int i=s,e=end;        //快速排序        while(i<e){            while(e>i&&temp<=input[e]){                e--;            }            input[i++]=input[e];            while(e>i&&temp>=input[i]){                i++;            }            input[e]=input[i];        }        input[e]=temp;        //如果k==e,说明e之前的都是小于e的,k〉e还需要排序后面的,e〉k要排序前面的        if(e==k)            return;        else if(e<k){            quicksort(input, e+1, end, list, k);        }else{            quicksort(input, s, e-1, list, k);        }    }    public static void main(String[] args) {        int[] a={4,5,1,6,2,7,3,8};        Solution13 b = new Solution13();        System.out.println(b.GetLeastNumbers_Solution(a,4));    }}
0 0
原创粉丝点击