最小的K个数

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

方法一 直接排序

通过对数组排序,可得到最小的K个数,时间复杂度O(N*lgN)

方法二 变异的快排

现在一个哨兵,对两次的进行筛选,大于哨兵的值再右侧,小于哨兵的值在左侧。

如果哨兵的位置index>K,对于[begin ~ index-1]再次快排。

如果哨兵的位置index<K,对于[index+1 ~ end]再次快排。


结果得到的最小的K个数不是有序的。

代码如下

import java.util.ArrayList;
import java.util.Random;

public class Solution {
	public static void main(String[] args) {
		Solution s = new Solution();
		ArrayList<Integer> result = s.GetLeastNumbers_Solution(new int[] { 0,1,1,1,1,1,1,1,5,1,1,0 }, 4);
//		ArrayList<Integer> result = s.GetLeastNumbers_Solution(new int[] { 4, 5, 1, 6, 2, 7, 3, 8 }, 6);

		System.out.println(result);
	}

	public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
		ArrayList<Integer> result = new ArrayList<>();
		if (k <= input.length && k > 0) {
			quickSort(input, k, 0, input.length - 1);
			for (int i = 0; i < k; ++i)
				result.add(input[i]);
		}
		return result;
	}

	private void quickSort(int[] input, int k, int begin, int end) {
		// 终止条件
		if (begin >= end) return;

		// 选择哨兵
		Random random = new Random();
		int index = begin + random.nextInt(end - begin);

		int tmp = input[index];
		int i = begin, j = end;

		// 快排
		while (i < j) {
			while (i < j && input[i] < tmp)
				++i;
			input[index] = input[i];
			index = i;

			// 注意是 input[j] >= tmp
			while (i < j && input[j] >= tmp)
				--j;
			input[index] = input[j];
			index = j;
		}
		input[index] = tmp;

		if (index == k - 1)
			return;

		if (index > k - 1) {
			quickSort(input, k, begin, index - 1);
		} else {
			quickSort(input, k, index + 1, end);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值