JZ29 最小的K个数

JZ29 最小的K个数

题目描述:

给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。如果K>数组的长度,那么返回一个空的数组

示例:

输入:
[4,5,1,6,2,7,3,8],4 

返回值:
[1,2,3,4]

题解:

方法一:排序

1.思路:

思路很简单,直接将所给的数组排序,直接返回前k个值。
可以用java所给的sort 函数

2.复杂度:

时间复杂度:O(nlongn)
空间复杂度:O(1)

3.代码:

import java.util.*;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
// 方法一:排序
        ArrayList<Integer> array = new ArrayList<>();
        
        if(input.length<k)
            return array;
        
        Arrays.sort(input);
        for(int i=0; i<k; i++){
            array.add(input[i]);
        }
        
        return array;

    }

    }
}

方法二:优先队列

1.思路:

可以利用优先队列的特性,可以直接更新容量为k的队列中的值,只需遍历一次题目所给的数组就可以将其中最小的k个值获取出来。
注意优先队列其实是利用大根堆进行插入。

2.复杂度:

时间复杂度:O(nlongk), 更新一次优先队列时间复杂度为O(longk), 一共遍历n个元素
空间复杂度:O(k)

3.代码:

import java.util.*;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {

        
// 方法二:优先队列
        
        ArrayList<Integer> array = new ArrayList<>();
        
        if(k>input.length || k==0)
            return array;
        //定义优先队列从大到小排列
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){
            @Override
            public int compare(Integer i1,Integer i2){
                return i2-i1;    
            }
        });
       
        for(int i=0; i<k; i++){
            queue.add(input[i]);
        }
        
        for(int i=k; i<input.length; i++){
            if(queue.peek()>input[i]){
                queue.poll();
                queue.add(input[i]);
            }
        }
        
        for(int i=0; i<k; i++){
            array.add(queue.poll());
        }
        return array;



    }

    }
}

方法二:快排思想

1.思路:

想一下快排的基本思路是什么?
对数组[left,right]进行一次快排之后,将数组分为 [lleft,mid-1],mid,[mid+1,right]三个区间;
其中[lleft,mid-1]区间的数值都小于坐标为mid的值,如果mid==k时说明最小的k个数为坐标 [lleft,mid-1],mid所对应的值。

2.复杂度:

时间复杂度:平均时间复杂度为O(n)
空间复杂度:O(1)

3.代码:

import java.util.*;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {


// 方法三:快排思想
        ArrayList<Integer> array = new ArrayList<>();
        
        if(k>input.length || k==0)
            return array;
        
        quickSort(input, 0, input.length-1, k-1, array);
        return array;

    }
    
    void quickSort(int[] input, int left, int right, int k, ArrayList<Integer> array ){
        int start = left;
        int end = right;
        
        while(start < end){
            while(start<end && input[left] <= input[end]) end--;
            
            while(start<end && input[left] >= input[start]) start++;
            
            int temp = input[start];
            input[start] = input[end];
            input[end] = temp;
          
        }
        int temp = input[left];
        input[left] = input[start];
        input[start] =temp;
        
        if(start < k){
            quickSort(input, start+1, right, k, array);
        }else if(start > k){
            quickSort(input, left, start-1, k, array);
        }else{
            for(int i=0; i<=k; i++){
                array.add(input[i]);
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值