魔塔游戏
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 58 ms, 内存: 30.1 MB
/**
* 思路:
* 1. 先计算所有房间血量变化的总和。
* 2. 如果总和加上初始血量小于1,返回-1。
* 3. 否则,使用Stream API计算当前最小血量,并使用优先队列记录负数房间。
* 4. 最后返回调整次数。
*/
import java.util.Arrays;
import java.util.PriorityQueue;
public class MagicTowerStream {
public int magicTower(int[] nums) {
long totalHealth = Arrays.stream(nums).sum();
if (totalHealth < 0) return -1;
long currentHealth = 1;
PriorityQueue<Integer> pq = new PriorityQueue<>();
int adjustments = 0;
for (int num : nums) {
currentHealth += num;
if (num < 0) {
pq.add(num);
}
if (currentHealth < 1) {
currentHealth -= pq.poll();
adjustments++;
}
}
return adjustments;
}
}
解释
方法:
为了确保小扣在游戏中始终保持正的血量,题解使用贪心策略和优先队列(最小堆)来解决问题。整个思路是在遍历房间时,记录所有遇到的怪物(负数)。如果小扣的血量在任何点变为非正数,将最大的负数(即堆顶元素,因为是最小堆,存负数时绝对值最大的会在堆顶)移至房间数组的末尾,即延迟与这个怪物的战斗,并从总血量中减去这个数值。这个操作可视为将最危险的怪物延后处理,以便小扣在之前的房间中可能获得更多的血量。最后,如果经过所有调整后小扣的血量仍然不是正数,则返回-1,表示无法通过所有房间,否则返回调整次数。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在使用优先队列(最小堆)存储怪物时,为什么选择存储怪物而不是补血道具,这种选择对算法的效果有何影响?
▷🦆
堆中存储负数的方式能确保每次移出的是绝对值最大的怪物吗?如何通过负数的存储实现这一点?
▷🦆
在代码中,`hp += num` 后紧接着检查 `hp <= 0` 来决定是否需要调整。这种检查方式是否可能遗漏某些情况,从而影响到调整策略的正确性?
▷