剑指offer40题

求TOP K数据问题。

一般的思路是,求最小值,用最大堆,求最大值,用最小堆。

拿球最大值来看。用最小堆,先对一个数组的前K个数组进行一个建堆操作,建立最小堆。然后对剩余数组进行选择,如果比堆中最小值的数据大,则替换最小值,然后更新堆,如果比最小值还小,则丢弃。

下面给出代码。我先贴上最小堆的代码。

package com.tools;

public class MinHeap {
	
	public int[] num;
	
	public MinHeap(int[] num){
		this.num = num;
		build();
	}
	
	//交换数据
	private void swap(int i , int j){
		int temp;
		temp = i;
		i = j;
		j = temp;
	}
	
	//初始化构造二叉堆
	private void build(){
		
		for(int i = 0 ; i <= num.length/2-1; i++){
			Heap(i);
		}
		
	}

	//对堆进行整理
	private void Heap(int index){
		
		int small = index;
		int left,right;
		left = (index+1)*2-1;
		right = (index+1)*2;
		if(left<num.length&&num[left]<num[index])
			small = left;
		if(right<num.length&&num[right]<num[small])
			small = right;
		if(small == index)
			return;
		int temp;
		temp = num[small];
		num[small] = num[index];
		num[index] = temp;
		Heap(small);
	}
	
	public int GetRoot(){
		return num[0];
	}
	
	public void SetHeadValue(int value){
		num[0] = value;
		Heap(0);
	}
	
}

  下面给出实验代码。

package com.algorithm05;

import java.util.Scanner;
import com.tools.MinHeap;


public class Algorithm40 {
	
	
	public static void main(String[] args) {
		
		int[] num = new int[]{5,2,1,4,8,12,3,100,2000,30,50};
		Scanner scanner = new Scanner(System.in);
		int k;
		k = scanner.nextInt();
		int[] topK = new int[k];
		//首先将数组中前k个数放入topk数组中。
		for(int i = 0 ; i < k ; i++){
			topK[i] = num[i];
		}
		//将topk数组转换为最小堆
		MinHeap minHeap = new MinHeap(topK);
		
		//前k个数据进入topk数组中,之后对数组中剩余数组进行最小堆的匹配
		for(int j = k ; j < num.length; j++){
			//如果数组中的值比topk最小的值还要小,则对其进行更换。并更新topk的数组的结构
			if(num[j]>minHeap.num[0])
			{
				minHeap.num[0] = num[j];
				minHeap.SetHeadValue(num[j]);
			}
		}
		System.err.println("pause");
	}
	
}

  

原文地址:https://www.cnblogs.com/CloudStrife/p/7368516.html