剑指offer_最小k个数(java)

剑指offer_最小k个数(java)

题目描述

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

思路解析

使用partition()方法,基于数组第k个数调整,使得比k小的数字都位于其左边
注释有详细解析

java代码

import java.util.ArrayList;
/*输入n个整数,找出其中最小的K个数。
例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。*/
public class Solution_KLeastNumbers {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        //根据方法返回类型,定义返回对象
        ArrayList<Integer> KLeast = new ArrayList<Integer>();
        //数组为空,或者k小于等于0,或者k超过了数组长度,直接返回空的ArrayList
        if (input == null || k <= 0 || k > input.length)
            return KLeast;
        
        int left = 0;
        int right = input.length - 1;
        //获取partition()方法返回的值(第left个的下标left)
        int index = partition(input, left, right);
        //循环退出条件,排好了第k-1个,因为从第0个开始,即已经排好前k个
        while (index != k - 1) {
            if (index < k - 1) {
                left = index + 1;
                //从下一个开始继续比较交换
                index = partition(input,left,right);
            } else {
                right = index - 1;
                index = partition(input,left,right);
            }
        }
        //输出前k个数
        for(int i = 0;i < k; i++)
            KLeast.add(input[i]);
        return KLeast;
    }
    
        private int partition(int[] arr,int left,int right){
                int tempkey = arr[left];
                int temp;
                while(left < right){	//递归出口
                    //从右往左扫描,当右边比tempkey大,继续往左比较(right--),直到找到第一个比它tempkey的(while退出)
                    while(left < right && arr[right] >= tempkey)
                        right--;
                    //交换
                    temp = arr[left];
                    arr[left] = arr[right];
                    arr[right] = temp;
                    //从左往右扫描,当左边比tempkey小,继续往右比较(left++),直到找到第一个比tempkey大的(while退出)
                    while(left < right && arr[left] <= tempkey)
                        left++;
                    //交换
                    temp = arr[left];
                    arr[left] = arr[right];
                    arr[right] = temp;
                }
                //返回目前已经排好的第left个的下标
                return left;
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值