1. 程式人生 > >大頂堆,n個數中找最小的k個數

大頂堆,n個數中找最小的k個數

package com.alo.offer;

import java.util.Scanner;

/**
 * n個數中找到最小的m個數 使用大頂堆
 * n個書中找到最大的m個數 使用小頂堆
 * @author Administrator
 *
 */
public class MaxHeap {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int k = sc.nextInt();
		MaxHeap mh = new MaxHeap(k);
		for(int i=0;i<n;i++) {
			mh.add(sc.nextInt());;
		}
		int []rs = mh.getData();
		for(int i:rs) System.out.print(i+" ");
		sc.close();
	}
	private int [] a ;
	public MaxHeap(int k){
		this.a = new int[k+1]; //下標從1開始
		for(int i=1;i<=k;i++) {
			this.a[i]= Integer.MAX_VALUE;
		}
		
	}
	public int getLength() {
		return a.length;
	}
	public int left(int i) {
		return i<<1;
	}
	public int right(int i) {
		return (i<<1)+1;
	}
	public void add(int e) {
		if(e<a[1]) { //如果比大頂堆的最大數小的話,將其新增到堆中
			a[1]=e;
			adjustHeap(1);
		}
	}
	private void adjustHeap(int root) {
		// TODO Auto-generated method stub
		int l=this.left(root); 
		int r =this.right(root);
		int max =root;
		if(l<this.getLength()&&a[l]>a[max])max=l;
		if(r<this.getLength()&&a[r]>a[max])max=r;//root的左右孩子和自己比較,找到當中值最大的下標,如果就是root的話,那麼不用進行調整,否則,root和最大的值交換;
		if(max==root) {							//然後遞迴判定交換後的下標作為根節點,是否符合root最大的條件
			return;
		}
		swap(root,max);
		this.adjustHeap(max);
	}
	private void swap(int root, int max) {
		// TODO Auto-generated method stub
		int temp =a[root];
		a[root]=a[max];
		a[max]=temp;
	}
	public int [] getData() {
		return this.a;
	}
}

相關推薦

n個數k個數

package com.alo.offer; import java.util.Scanner; /** * n個數中找到最小的m個數 使用大頂堆 * n個書中找到最大的m個數 使用小頂堆

n個數k個數問題求解(要求複雜度為O(n))

  首先我們都知道可以將n個元素建一個最(大|小)堆,O(n)。 下面一個很常見的做法就是,每步從堆頂拿掉一個元素,拿k次,就把前k個元素拿出來了。但問題是,每步拿掉一個元素之後,都需要log(n)的時間來將堆再次最­(大|小)化。所以拿k次的複雜度就是 klog(n)。有沒

C++ priority_queue用法(

cplusplus.com template <class T, class Container = vector<T>, class Compare = less<typename Container::value_type&g

排序

一如既往,先上詳細的過程圖。 應用場景 比如求10億個數中的最大的前10個數,時時構建只有10個元素的小頂堆,如果比堆頂小,則不處理;如果比堆頂大,則替換堆頂,然後依次下沉到適當的位置。 比如求10億個數中的最小的前10個數,時時構建只有10個元素的大頂堆,如果比堆頂大

通過排序從1億個數找到的100個數

package com.my.util; import java.util.Arrays; import java.util.Date; import java.util.Random; public class Top100 { public static vo

&&排序&&N個數K值&&優先順序佇列

學習二叉樹後,有一個東西需要我們來關注下,就是堆,對於堆,來說我們可以把堆看作一顆完全二叉樹。這裡我們也可以叫做二叉堆。 二叉堆滿足二個特性: 1.父結點的鍵值總是大於或等於(小於或等於)任何一個子節點的鍵值。 2.每個結點的左子樹和右子樹都是一個二叉堆(

n個整數出連續m個數加和是Java版

即上一篇Python版取連續加和最大的整數後,本篇部落格帶來Java版取連續加和最大的整數。總體的思路入上一次部落格中所述,就不在過多的闡述,關鍵就在於如何應用Java API寫出相同邏輯的程式碼。

n個整數出連續m個數加和是Python版

最近在看資料時看到了一個如標題所示的面試題,面試題是Java版,正好最近在學Python,就先用Python實現了。畢竟life is short,use python(玩笑話,演算法設計思路是共同的

出三個數值或者

int big 次方 表示 比較運算 直接 最大 inpu 比較運算符 算數運算符:+-*/ //()整除 %取余 **次方 比較運算符:>< >= <= !=不等於 ==等於 #單個等於表示賦值 找出三個數中的最大值:

演算法題 90:從多個數值(百度筆試題

題目:有n個長度均為m的整型陣列,陣列中的元素都是從小到大有序排列,從所有這些陣列m*n個數中,找出值最大的前k個。請給出思路和時間複雜度。 類似賽馬問題做法 本Markdown編輯器使用StackEdit修改而來,用它寫部落格,將會帶來全新的體驗哦: Markdown和擴

C++出一個二維陣列的鞍點即該位置上的元素在該行上在該列上(也可能沒有鞍點)

今日正式用csdn部落格記錄,回顧我所學到的知識,分享一些我的人生感悟和自身經歷。也希望未來通夠過此平臺和更多喜愛程式設計的人交流學習。 道聽途說再加上自己的感悟,認為程式設計最重要的是思想,而不是語言本身,語言只是個工具。所以我們得先學思想。遇到問題,應該先想如果是自己去做會怎麼處理,但我們不

從100萬個數的前100個數

1.演算法如下:根據快速排序劃分的思想 (1) 遞迴對所有資料分成[a,b)b(b,d]兩個區間,(b,d]區間內的數都是大於[a,b)區間內的數 (2) 對(b,d]重複(1)操作,直到最右邊的區間個數小於100個。注意[a,b)區間不用劃分 (3) 返回上

在Java的一種優雅實現

既然小頂堆已經實現出來,那麼同理大頂堆也順理成章實現出來,只需稍微改動幾個關鍵部門的程式碼。 /** * 大頂堆/最大堆實現 * * @author stephenshen * */ public class MaxHeap { // 堆得儲存結構:陣列 p

【演算法】大堆()及)的實現

此坑待埋。 下面來說一說具體演算法。 堆排序解釋第一篇(描述不太清楚) 1.堆   堆實際上是一棵完全二叉樹,其任何一非葉節點滿足性質:   Key[i]<=key[2i+1]&&Key[i]<=key[2i+2

輸入一個數組長度動態建立陣列所有元素隨機生成輸出元素

int length = 0;         printf("輸入一個數組長度:");         scanf("%d", &length);         int *p = malloc(sizeof(int) * length);         for

位運算---不用任何比較判斷出兩個數

【題目】   給定兩個32位整數a和b,返回a和b中較大的一個。要求不能使用比較判斷。 【基本思路】  方法一。得到a - b的符號就可以知道a和b哪一個大了。具體過程參照如下程式碼: int getMax1(int a, int b) {

10億個數的10000個數(top K問題)

        前兩天面試3面學長問我的這個問題(想說TEG的3個面試學長都是好和藹,希望能完成最後一面,各方面原因造成我無比想去鵝場的心已經按捺不住了),這個問題還是建立最小堆比較好一些。         先拿10000個數建堆,然後一次新增剩餘元素,如果大於堆頂的數(1

10億個數的10000個數(top K問題)

前兩天面試3面學長問我的這個問題(想說TEG的3個面試學長都是好和藹,希望能完成最後一面,各方面原因造成我無比想去鵝場的心已經按捺不住了),這個問題還是建立最小堆

python 出list或者個數的索引

nums = [1,8,2,23,7,-4,18,23,24,37,2] result = map(nums.index, heapq.nlargest(3, nums)) temp=[] Inf =

定義一個數獲取陣列值和

思路 : 我們定義一個數組,再定義一個max變數 用來儲存最大值  ; 再定義一個min變數,用來儲存最小值; 我們遍歷陣列,假如當前值大於max,就把當前值賦值給max; 假如當前值小於min,就把當前值賦值給min; 我們給下示例程式碼: 1 2