《剑指offer》NO40 最小的K个数 详解 <Java实现>

//题目描述:
//输入n个整数,找出其中最小的K的数.例如,输入4,5,1,6,2,7,3,8折8个数,
//则最小的4个数字是1,2,3,4.
public class Solution
{
    //解题思路:
    //要找出最小的K的数,首先考虑到排序,再选出前K个数.但是还不够快.这样的时间复杂度是O(nlogn).

    //借用快排的思想.只要先找出找出第K小的元素,再用快排,这样K左边就是比K 小的元素.时间复杂度为O(1).
    //但是要找出第K小的元素也是一个问题.所以直接循环判断整个数组,找出快排一次后左边的元素个数是K个,就找到了最小的K个元素.
    //这样的时间复杂度是O(n) + O(1).
    // 但是只有当允许修改数组元素时才可以使用

    public ArrayList<Integer> getKthNumber(int[] nums, int k)
    {
        ArrayList<Integer> res = new ArrayList<>();

        //初始判断
        if (nums.length == 0 || nums == null || k < 0 || k > nums.length)
        {
            return null;
        }
        int l = 0, h = nums.length - 1;
        //开始循环判断,有点类似二分法.
        while (l < h)
        {
            int j = quickSelect(nums, l, h);
            if (j > k)
            {
                h = j - 1;
            }
            else if (j < k)
            {
                l = j + 1;
            }
            else
            {
                break;
            }
        }
        //从index为0的到K-1的是最小一K个数.
        for (int i = 0; i < k; i++)
        {
            res.add(nums[i]);
        }
        return res;
    }

    //快排
    private int quickSelect(int[] nums, int l, int h)
    {
        int p = nums[l];
        int i = l, j = h + 1;
        while (i < j)
        {
            while (i < j && nums[++i] < p) ;
            while (i < j && nums[--j] > p) ;

            swap(nums, i, j);
        }
        swap(nums, l, j);
        return j;
    }

    private void swap(int[] nums, int i, int j)
    {
        int t = nums[i];
        nums[i] = nums[j];
        nums[j] = t;
    }
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值