连接木棍的最低费用
难度:
标签:
题目描述
代码结果
运行时间: 108 ms, 内存: 17.0 MB
/*
题目思路:
连接木棍的最低费用可以通过哈夫曼树的思想解决。
我们需要不断地将当前最短的两根木棍连接起来,并将其新的长度放回到候选池中,
重复这个过程直到所有的木棍都连接成一根。
在实现时,我们可以使用优先队列(最小堆)来每次快速找到最短的两根木棍。
使用Java Stream API无法直接解决该问题,因为它涉及到优先队列等数据结构。
但可以通过转换来辅助实现。
*/
import java.util.Arrays;
import java.util.PriorityQueue;
public class Solution {
public int connectSticks(int[] sticks) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
Arrays.stream(sticks).forEach(pq::offer);
int totalCost = 0;
while (pq.size() > 1) {
int first = pq.poll();
int second = pq.poll();
int cost = first + second;
totalCost += cost;
pq.offer(cost);
}
return totalCost;
}
}
解释
方法:
这个问题可以通过优先队列(最小堆)来解决。首先,将所有的木棍长度放入一个最小堆中。在每一步中,从堆中取出两个最短的木棍,并计算将它们连接起来的成本,即两者之和。将这个成本加入到总成本中,并把新形成的木棍(即两者之和)加回到最小堆中。这个过程一直重复,直到堆中只剩下一个木棍。这时,累计的总成本就是连接所有木棍的最低费用。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在这个问题中选择使用最小堆(优先队列)而不是其他数据结构如数组或链表?
▷🦆
在取出两个最短的木棍进行合并时,如果它们的长度相同,会有什么特殊的影响吗?
▷🦆
在合并木棍的过程中,每次都将新形成的木棍加回到最小堆中,这种操作是否会影响堆的性能,比如导致堆的重构?
▷🦆
合并操作一直持续到只剩一个木棍,这是否意味着总是存在一个最佳方案使得总成本最小,还是说结果依赖于木棍的初始排列顺序?
▷相关问题
合并石头的最低成本
有 n
堆石头排成一排,第 i
堆中有 stones[i]
块石头。
每次 移动 需要将 连续的 k
堆石头合并为一堆,而这次移动的成本为这 k
堆中石头的总数。
返回把所有石头合并成一堆的最低成本。如果无法合并成一堆,返回 -1
。
示例 1:
输入:stones = [3,2,4,1], K = 2 输出:20 解释: 从 [3, 2, 4, 1] 开始。 合并 [3, 2],成本为 5,剩下 [5, 4, 1]。 合并 [4, 1],成本为 5,剩下 [5, 5]。 合并 [5, 5],成本为 10,剩下 [10]。 总成本 20,这是可能的最小值。
示例 2:
输入:stones = [3,2,4,1], K = 3 输出:-1 解释:任何合并操作后,都会剩下 2 堆,我们无法再进行合并。所以这项任务是不可能完成的。.
示例 3:
输入:stones = [3,5,1,2,6], K = 3 输出:25 解释: 从 [3, 5, 1, 2, 6] 开始。 合并 [5, 1, 2],成本为 8,剩下 [3, 8, 6]。 合并 [3, 8, 6],成本为 17,剩下 [17]。 总成本 25,这是可能的最小值。
提示:
n == stones.length
1 <= n <= 30
1 <= stones[i] <= 100
2 <= k <= 30