最高的广告牌
难度:
标签:
题目描述
代码结果
运行时间: 151 ms, 内存: 16.7 MB
// 思路:同样是使用动态规划的方法,通过 Java Stream API 来实现。我们利用 Stream 的操作来遍历和更新 dp 集合。
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class BillboardHeightStream {
public int tallestBillboard(int[] rods) {
Map<Integer, Integer> dp = new HashMap<>();
dp.put(0, 0);
for (int rod : rods) {
Map<Integer, Integer> cur = dp.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue));
cur.forEach((d, h) -> {
dp.merge(d + rod, h, Math::max);
dp.merge(Math.abs(d - rod), h + Math.min(d, rod), Math::max);
});
}
return dp.getOrDefault(0, 0);
}
}
解释
方法:
此题解使用了分治加动态规划的方法。首先将钢筋数组分为两部分,对每部分独立求解可能的差值和相应的最大高度。这里使用一个字典来存储从差值到最大高度的映射。对于每根钢筋,更新两种情况:将它加到一边或从一边减去。这样,可以得到包含所有可能差值的字典。然后,将两部分的结果合并,查找两个字典中相反的键(即差值相等但符号相反,表示两边可以平衡),并计算这些情况的最大高度。最终结果是所有匹配差值组合中的最大高度。
时间复杂度:
O(2^(n/2))
空间复杂度:
O(2^(n/2))
代码细节讲解
🦆
为什么在更新字典时需要使用临时列表`list(f.items())`来避免在迭代中修改字典?能否直接在迭代`f`的过程中更新?
▷🦆
在函数`h(rods)`中,为何选择将钢筋加到一边或从一边减去,并且如何保证这两种情况能够覆盖所有可能的子集和差值?
▷🦆
题解中提到通过分治法将钢筋分为两部分,这种分法是否总是最优的?会不会存在某些情况下,不均等的分割会得到更好的结果?
▷