有20个数组,每个数组里面有500个数,升序排列,求出这10000个数中的最大500个数。并求复杂度。【百度2012年的一道算法题】

题目描述

有20个数组,每个数组有500个升序排列的数,求出这10000个数中前500个最大的数,并求复杂度。

解题思路

用一个大小为20的最大堆,通过维护这个堆,每次选出一个最大的数,如此往复500次,所以时间复杂度500 * log(20)

代码

这道题比较有意思的是利用最大最小堆求解,以及求解最大堆解决的复杂度。代码分为两个部分,第一部分是我自己写的一个简略最大堆作为基础数据结构: MaxHeap.java

package wheels;

/**
 * 最大堆的简单实现
 * 类比最小堆,在此主要是锻炼自己迅速写各式各样的轮子,再写一遍
 * @author XZP
 * 一组测试数据: 12 45 -11 69 1 95 9 78 64 21
 */
public class MaxHeap {
   
	private int INF = -9999999; // 认为规定的最小值
	private int[] arr;
	public MaxHeap (int size) {
   
		arr = new int[size + 1]; // 下标从1开始
		for (int i = 0; i <= size; i++) {
    // 牺牲空间和一定时间来保证数组能存零值
			arr[i] = INF;
		}
	}
	/**
	 * 向最大堆中插入一个元素使其任然满足最大堆
	 * @param data 待插入数据
	 * @return 成功为true,失败将打印异常栈
	 */
	public boolean push(int data) {
   
		int index = this.index();
		try {
   
			this.arr[index] = data;
			siftup(index);  // 插入数组末尾之后需要向上调整使其满足最大堆
		} catch (IndexOutOfBoundsException e) {
   
			e.printStackTrace();
		}
		return true;
	}
	/**
	 * @return 数组能存储的最大size
	 */
	public int size() {
   
		return arr.length - 1;
	}
	/**
	 * 获取当前能插入值得数组下标
	 * @return 数组中已有值长度  + 1
	 */
	private int index() {
   
		int usedLength = 0;
		for (int i = 1; i <= this.size(); i++) {
   
			if (this.arr[i] != INF) {
   
				usedLength++;
			}
		}
		return usedLength + 1;
	}
	/**
	 * 从最小堆中取最小的那个元素,并调整使其一直满足最小堆
	 * @return 数组不为空则返回最小的元素,否则返回人为规定的INF值
	 */
	public int pop() {
   
		if (!isLegal(1)) {
    // 每次取第一个元素(下标值为1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值