letcode最小的K个数(java)

描述

给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。

数据范围:0\le k,n \le 100000≤k,n≤10000,数组中每个数的大小0 \le val \le 10000≤val≤1000

要求:空间复杂度 O(n)O(n) ,时间复杂度 O(nlogn)O(nlogn)

示例1

输入:

[4,5,1,6,2,7,3,8],4 

复制返回值:

[1,2,3,4]

复制说明:

返回最小的4个数即可,返回[1,3,2,4]也可以       

解决问题思路:时间复杂度 O(nlogn),空间复杂度o(n),典型得分治算法求解问题(附:其实堆排序也可以,堆排序空间复杂度只有O(1),性能更佳),本提附上分治法求解得代码

import java.util.ArrayList;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        Merge_sort(input,0,input.length-1);
        ArrayList<Integer> list=new ArrayList();
        int index=1;
        while(index<=k){
            list.add(input[index++-1]);
        }
        return list;
        
    }
    
     public  void Merge_sort(int[] A,int p,int r){//p为起始位置,r为结束位置
        int q = (p+r)/2;//q为二分位置
        if(p < r){
            //递归调用          
            Merge_sort(A,p,q);//递归解决前半部分
            Merge_sort(A,q + 1,r);//递归解决后半部分
            //归并排序数据元素
            Merge(A,p,q,r);//最后将所有有序数组完成归并
        }
    }
    
    public  void Merge(int[] A,int p,int q,int r){

        int[] tmp = new int[r-p+1];//声明一个临时数组,长度为要归并数组的长度
        int i = p;   //记住左边数组第一个元素的下标
        int j = q+1; //记住右边数组第一个元素的下标
        int k = 0;      
        while(i <= q && j <= r){
            //左边数组元素和右边数组元素比较,把小的元素赋给临时数组
            if(A[i] <= A[j]){               
                tmp[k++] = A[i++];
            }
            else{               
                tmp[k++] = A[j++];
            }
        }
        //把左边剩余的数组元素赋给临时数组
        while(i <= q){          
            tmp[k++] = A[i++];
        }
        //把右边剩余的数组元素赋给临时数组
        while(j <= r){          
            tmp[k++] = A[j++];
        }
        //用临时数组元素覆盖原数组元素
        for(int k2 = 0;k2 < tmp.length;k2++){           
            A[k2+p] = tmp[k2]; 
        }
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值