top k

问题:从arr[1, n]这n个数中,找出最大的k个数,这就是经典的TopK问题。

1、Java基于TreeSet实现

public static void main(String[] args) throws Exception, RemoteException {
		int[] a = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 1, 8 };
		TreeSet<Integer> set = new TreeSet<Integer>();
		for (int i = 0; i < a.length; i++) {

			int value = a[i];
			if (set.size() < 5)
				set.add(value);
			else {
				Iterator<Integer> it = set.descendingIterator();
				int setMax = it.next();
				if (setMax > value) {
					it.remove();
					set.add(value);
				}
			}
		}
		System.out.println("topk之后:" + set);
	}

2、基于大顶堆的top k算法
我们先创建一个大小为k的数组来存储最小的k个数字,接下来我们从输入的n个数中读取一个数,如果容器还没有满则直接插入容器;若容器已经满了,则我们此时需要将容器中最大的数字和待插入的数字做比较,如果待插入的数值小于容器中的最大值,则需要将容器中的最大值删除,将新值插入,否则不做任何处理。这种算法适合海量数据的情况下。

public static void main(String[] args) throws Exception, RemoteException {
		int[] a = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 1, 8 };
		System.out.println("top k结果:" + Arrays.toString(topK(a, 5)));
	}

	public static int[] topK(int[] nums, int k) {
		if (k >= nums.length)
			return nums;
		int[] res = new int[k];
		for (int i = 0; i < k; i++) {
			res[i] = nums[i];
		}
		for (int i = (k - 1) / 2; i >= 0; i--) {// 建一个初始堆
			sift(res, i);
		}
		// 从nums中第k项开始,与大顶堆的根节点依次比较,并进行调整
		for (int i = k; i < nums.length; i++) {
			if (nums[i] < res[0]) {
				res[0] = nums[i];
				sift(res, 0);
			}
		}
		return res;
	}

	private static void sift(int[] nums, int index) {// 针对某个节点进行调整,使之符合大顶堆
		if (index >= nums.length)
			return;
		int i = index;
		int j = 2 * i + 1;
		while (j < nums.length) {
			if (j + 1 < nums.length && nums[j] < nums[j + 1]) {
				j++;// j指向较大的子节点
			}
			if (nums[i] < nums[j]) {// 调整节点
				int temp = nums[i];
				nums[i] = nums[j];
				nums[j] = temp;
				i = j;// 追踪调整
				j = 2 * (i + 1) - 1;
			} else {
				break;
			}
		}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值