本文已参与「新人创作礼」活动,一起开启掘金创作之路
题目
一块金条切成两半,是需要花费和长度数值一样的铜板的。 比如长度为20的金条,不管切成长度多大的两半, 都要花费20个铜板。一群人想整分整块金条,怎么分最省铜板
思路
这个题目需要用到堆的思想。具体的推导,可以参考哈弗曼编码树。
我们先用堆来保存数组里面的元素,然后弹出两个数,让他们相加成sum,然后让sum和ans相加,然后把sum压回堆。一次往复,每次得到新的sum都和ans相加,最后堆里面就只有一个元素的时候,返回ans就是答案。
举例
arr:【3,8,7,5,3,6】
先把数组arr放到小根堆里面
数组就变成了这样【3,3,5,6,7,8】
然后弹出两个分别是3和3
然后sum = 6
ans += sum
ans = 6
然后把6压回去
数组就变成了【5,6,6,7,8】
之后继续弹两个元素,让他们相加
sum = 11
ans += sum
ans = 17
把sum的值压回去
数组就变成了【6,7,8,11】
继续弹两个元素,让他们相加
sum = 13
ans += sum
ans = 30
把sum的值压回去
数组就变成了【8,11,13】
继续弹两个元素,让他们相加
sum = 19
ans += sum
ans = 49
把sum的值压回去
数组就变成了【13,19】
之后继续弹两个元素,让他们相加
sum = 32
ans += sum
ans = 81
把sum的值压回去
数组就变成了【32】
代码
public static int lessMoney1(int[] arr){
PriorityQueue<Integer> help = new PriorityQueue<>();
for(int i = 0;i<arr.length;i++){
help.add(arr[i]);
}
int sum = 0;
int ans = 0;
while(help.size() > 1){
sum = help.poll() + help.poll();
ans += sum;
help.add(sum);
}
return ans;
}
上述代码就是举例的时候的一个体现,创建一个小根堆,然后把数组里面的元素放到小根堆里面,之后就是弹出,相加,压回。