まとめ:ヒープ構造
5645 ワード
スタック構造は非常に重要です.そこで特にスタック構造に関する知識点を記録します.1.最も重要なスタックソートの問題:javaリファレンスコードは以下の通りです.
2.ハフマン問題の小根の山.1枚の金棒を半分に切るには、長さの数値と同じ銅板が必要です.例えば、長さが20の金の棒は、どんなに大きな半分に切っても、銅板が20個かかります.一群の人は金の棒全体を分けたいと思っていますが、どうやって最も節約した銅板を分けますか?例えば、所与の配列{10,20,30}は、合計3人を表し、全体の金条の長さは10+20+30=60である.金条は10,20,30の3つの部分に分けられる.もし、長さ60の金の棒を10と50に分け、60を使って長さ50の金の棒を20と30に分け、50を使って合計110銅板を使う.しかし、長さ60の金の棒を30と30に分け、60を使って長さ30の金の棒を10と20に分け、30を使って全部で90銅板を使う.配列を入力し、分割の最小コストを返します.
考え方:入力した配列をすべて小根の山の中に入れて、毎回小さい2つを取って、得られた和は更に山の中に入れて、途中で累積和を記録して、山の中に1つしか残っていないことを知っています.
JAvaリファレンスコードは以下の通りです.
3.入力:パラメータ1、正数配列costsパラメータ2、正数配列profitsパラメータ3、正数kパラメータ4、正数m costs[i]i番項目の費用profits[i]i番項目が費用を差し引いた後で稼ぐことができるお金(利益)kは、並列にできないことを示し、シリアルにできる最大k個の項目mは、最初の資金説明を示します.すぐに得られる収益は、次のプロジェクトをサポートすることができます.出力:あなたが最後に得た最大金額.
考え方:投資、あなたは現在の資金Wを持っていて、あなたは全部でK回投資することができて、しかも毎回1つしか投資できません.この問題を2つのスタックで解決し,小さなスタックはプロジェクトのcostに基づいて構築され,大きなスタックは各プロジェクトのprofitに基づいて構築される.我々は,小根スタック中のcostが現在のWより小さいプロジェクトを大根スタックに配置し,大根スタックの構築原理に基づいて,大根スタックが空になるまで最大収益を出して投資したり,K個の投資が締め切られたりする.JAvaリファレンスコードは以下の通りです.
package chapter2;
public class P79_heapSort {
public static void heapSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length; i++) {
heapInsert(arr, i);//maxHeap
}
int size = arr.length;
swap(arr, 0, --size);
while (size > 0) {
heapify(arr, 0, size);
swap(arr, 0, --size);// ,
}
}
public static void heapInsert(int[] arr, int index) {//maxHeap
while (arr[index] > arr[(index - 1) / 2]) {
swap(arr, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
public static void heapify(int[] arr, int index, int size) {//size-->heapSize
int left = index * 2 + 1;
while (left < size) {
int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;//left+1--->right
largest = arr[largest] > arr[index] ? largest : index;
if (largest == index) {
break;
}
swap(arr, largest, index);
index = largest;
left = index * 2 + 1;
}
}
public static void swap(int[] arr,int i,int j){
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
public static void main(String[] args) {
int[] arr={1,3,5,7,9,2,4,6,8};
heapSort(arr);
for(int num:arr){
System.out.print(num+" ");
}
}
}
2.ハフマン問題の小根の山.1枚の金棒を半分に切るには、長さの数値と同じ銅板が必要です.例えば、長さが20の金の棒は、どんなに大きな半分に切っても、銅板が20個かかります.一群の人は金の棒全体を分けたいと思っていますが、どうやって最も節約した銅板を分けますか?例えば、所与の配列{10,20,30}は、合計3人を表し、全体の金条の長さは10+20+30=60である.金条は10,20,30の3つの部分に分けられる.もし、長さ60の金の棒を10と50に分け、60を使って長さ50の金の棒を20と30に分け、50を使って合計110銅板を使う.しかし、長さ60の金の棒を30と30に分け、60を使って長さ30の金の棒を10と20に分け、30を使って全部で90銅板を使う.配列を入力し、分割の最小コストを返します.
考え方:入力した配列をすべて小根の山の中に入れて、毎回小さい2つを取って、得られた和は更に山の中に入れて、途中で累積和を記録して、山の中に1つしか残っていないことを知っています.
JAvaリファレンスコードは以下の通りです.
package zuoshen1;
import java.util.Comparator;
import java.util.PriorityQueue;
public class HuffmanTree {
public static int lessMoney(int[] arr){
if(arr==null||arr.length<1)
throw new RuntimeException("arr is null!");
PriorityQueue pq=new PriorityQueue<>(new MinheapComparator());// ,
for(int i=0;i1){//==1 break
cur=pq.poll()+pq.poll();
sum+=cur;
pq.add(cur);
}
return sum;
}
public static class MinheapComparator implements Comparator {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2; // < 0 o1 < o2
}
}
public static class MaxheapComparator implements Comparator {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1; // < o2 < o1
}
}
public static void main(String[] args) {
System.out.println(lessMoney(new int[]{10,20,30}));
}
}
3.入力:パラメータ1、正数配列costsパラメータ2、正数配列profitsパラメータ3、正数kパラメータ4、正数m costs[i]i番項目の費用profits[i]i番項目が費用を差し引いた後で稼ぐことができるお金(利益)kは、並列にできないことを示し、シリアルにできる最大k個の項目mは、最初の資金説明を示します.すぐに得られる収益は、次のプロジェクトをサポートすることができます.出力:あなたが最後に得た最大金額.
考え方:投資、あなたは現在の資金Wを持っていて、あなたは全部でK回投資することができて、しかも毎回1つしか投資できません.この問題を2つのスタックで解決し,小さなスタックはプロジェクトのcostに基づいて構築され,大きなスタックは各プロジェクトのprofitに基づいて構築される.我々は,小根スタック中のcostが現在のWより小さいプロジェクトを大根スタックに配置し,大根スタックの構築原理に基づいて,大根スタックが空になるまで最大収益を出して投資したり,K個の投資が締め切られたりする.JAvaリファレンスコードは以下の通りです.
package zuoshen1;
import java.util.Comparator;
import java.util.PriorityQueue;
public class FindMaximizedCapital {
public static class Node{
int c;
int p;
public Node(int c,int p){
this.c=c;
this.p=p;
}
}
public static class MinComparator implements Comparator{
@Override
public int compare(Node o1,Node o2){
return o1.c-o2.c;//min cost
}
}
public static class MaxComparator implements Comparator{
@Override
public int compare(Node o1,Node o2){
return o2.p-o1.p;//max profit
}
}
public static int findMaximizedCapital(int k,int w,int[] cost,int[] profit){
if(k<0||w<0||cost==null||profit==null||cost.length!=profit.length)
throw new RuntimeException("run exception!");
Node[] nodes=new Node[cost.length];
PriorityQueue minQ=new PriorityQueue<>(new MinComparator());
PriorityQueue maxQ=new PriorityQueue<>(new MaxComparator());
for(int i=0;i=cost[i]//w ,
maxQ.add(minQ.poll());
}
if(maxQ.isEmpty()){
return w;
}
//else maxQ is not empty!
w+=maxQ.poll().p;
}
return w;
}
public static void main(String[] args) {
int[] cost={5,6,7,8,9,20};
int[] profit={1,2,3,5,6,10};
int w=10;
int k1=4;
int k2=6;
System.out.println(findMaximizedCapital(k1,w,cost,profit));
System.out.println(findMaximizedCapital(k2,w,cost,profit));
}
}