• 剑指offer_29:最小的k个数


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

    示例 1:
    输入:arr = [3,2,1], k = 2
    输出:[1,2] 或者 [2,1]

    示例 2:
    输入:arr = [0,1,2,1], k = 1
    输出:[0]

    限制:
    0 <= k <= arr.length <= 10000
    0 <= arr[i] <= 10000

    1、直接排序

    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            int[] res=new int[k];
            Arrays.sort(arr);
            for(int i=0;i<k;i++){
                res[i]=arr[i];
            }
            return res;
        }
    }
    

    2、快速选择(快排思想)

    快排就是在把元素分为两类,一边比基准小,一边比基准大,这道题只需要选择一侧的数据就行

    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            if(k==0){
                return new int[0];
            }else if(arr.length<=k){
                return arr;
            }
            part(arr,0,arr.length-1,k);
            int[] res=new int[k];
            for(int i=0;i<k;i++){
                res[i]=arr[i];
            }
            return res;
        }
        public void part(int[] a,int left,int right,int k){
            int num=quickSort(a,left,right);//获取分界值
            if(num==k){
                return;
            }else if(num>k){//缩小范围
                part(a,left,num-1,k);
            }else{
                part(a,num+1,right,k);
            }
        }
        public int quickSort(int[] a,int left,int right){
            int i=left;
            int j=right+1;
            int v=a[left];//a[left]作为分界点
            while(true){
                while(a[++i]<v){//向右找比分界点大的值
                    if(i==right){//直到范围的最右边
                        break;
                    }
                }
                while(a[--j]>v){//向左找比分界点小的值
                    if(j==left){//直到范围的最左边
                        break;
                    }
                }
                if(i>=j){//相遇退出
                    break;
                }
                swap(a,i,j);//未相遇,交换
            }
            swap(a,left,j);//将分界点放在正确的位置,只能用j,不能用i。例子:0 1 2 1
            return j;
        }
        public void swap(int[] a,int x,int y){
            int t=a[x];
            a[x]=a[y];
            a[y]=t;
        }
    }
    

    3、堆排序

    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            if(k==0){
                return new int[0];
            }else if(arr.length<=k){
                return arr;
            }
            Queue<Integer> heap=new PriorityQueue<>((v1,v2)->v2-v1);
            for(int i:arr){
                if(heap.size()<k){
                    heap.offer(i);
                }else if(heap.peek()>i){
                    heap.poll();
                    heap.offer(i);
                }
            }
            int[] res=new int[heap.size()];
            int index=0;
            for(int i:heap){
                res[index++]=i;
            }
            return res;
        }
    }
    
  • 相关阅读:
    前端开发者也可以酷酷地开发桌面程序
    V部落,V人事
    jq 正方体旋转
    jq 实现旋转木马
    jquery 获取元素(父节点,子节点,兄弟节点)
    Vue.js面试题整理
    Java面试必备技能
    在前后端分离的SpringBoot项目中集成Shiro权限框架
    正则表达式大全
    Docker容器日志查看与清理
  • 原文地址:https://www.cnblogs.com/xyz-1024/p/14410834.html
Copyright © 2020-2023  润新知