题目地址:
https://www.lintcode.com/problem/minimum-cost-to-connect-sticks/description
给定一个长度为 n n n的正整数数组 A A A,代表若干棒材的长度。每次焊接两个长度为 x x x和 y y y的棒材需要的费用是 x + y x+y x+y。如果需要将所有棒材焊接成 1 1 1根,问至少需要多少费用。
思路是贪心。每次都将最短的两个棒材焊接起来,所花费用即为答案。
证明参考https://blog.csdn.net/qq_46105170/article/details/113750503。
由于每次都需要找到最小的两个数,所以可以用最小堆来做。先poll两个数出来,然后算完了再将它们的和offer进堆。代码如下:
import java.util.List;
import java.util.PriorityQueue;
public class Solution {
/**
* @param sticks: the length of sticks
* @return: Minimum Cost to Connect Sticks
*/
public int MinimumCost(List<Integer> sticks) {
// write your code here
int res = 0;
// 直接将list当成参数传给PriorityQueue的话,会调用heapify,实际时间复杂度只有O(n);
// 不要将元素一个个offer进去,这样的时间复杂度是O(nlog n),更慢
PriorityQueue<Integer> minHeap = new PriorityQueue<>(sticks);
while (minHeap.size() >= 2) {
int min1 = minHeap.poll();
int min2 = minHeap.poll();
// 累加费用
res += min1 + min2;
minHeap.offer(min1 + min2);
}
return res;
}
}
时间复杂度 O ( n log n ) O(n\log n) O(nlogn),空间 O ( n ) O(n) O(n)。