题目描述
给定一个正数数组arr,arr的累加和代表金条的总长度,arr的每个数代表金条要分成的长度。规定长度为k的金条分成两块,费用为k个铜板。返回把金条分出arr中的每个数字需要的最小代价。
[要求]
时间复杂度为O(nlogn),空间复杂度为O(n)
输入描述:
第一行一个整数N。表示数组长度。
接下来一行N个整数,表示arr数组。
输出描述:
一个整数表示最小代价
示例1
输入
3
10 30 20
输出
90
解法一:类似哈夫曼树,借助堆实现
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine());
String[] ss = br.readLine().trim().split(" ");
int[] arr = new int[len];
for(int i=0;i<len;i++){
arr[i] = Integer.parseInt(ss[i]);
}
long res = getRes(arr);
System.out.println(res);
}
public static long getRes(int[] arr){
if(arr==null||arr.length==0) return 0;
//小根堆
PriorityQueue<Long> minHeap = new PriorityQueue<>();
//把所有值入堆
for(int i=0;i<arr.length;i++){
minHeap.add((long)arr[i]);
}
long sum = 0;
while(minHeap.size()>1){
long num1 = minHeap.poll();
long num2 = minHeap.poll();
sum += (num1+num2);
minHeap.add(num1+num2);
}
return sum;
}
}