LCP 30. 魔塔游戏 - 力扣(LeetCode)

题目描述

小扣当前位于魔塔游戏第一层,共有 N 个房间,编号为 0 ~ N-1。每个房间的补血道具/怪物对于血量影响记于数组 nums,其中正数表示道具补血数值,即血量增加对应数值;负数表示怪物造成伤害值,即血量减少对应数值;0 表示房间对血量无影响。

小扣初始血量为 1,且无上限。假定小扣原计划按房间编号升序访问所有房间补血/打怪,为保证血量始终为正值,小扣需对房间访问顺序进行调整,每次仅能将一个怪物房间(负数的房间)调整至访问顺序末尾。请返回小扣最少需要调整几次,才能顺利访问所有房间。若调整顺序也无法访问完全部房间,请返回 -1。

题目示例

输入:nums = 100,100,100,-250,-60,-140,-50,-50,100,150

输出:1

解释:初始血量为 1。至少需要将 nums3 调整至访问顺序末尾以满足要求。

解题思路

思路

我们按照原计划访问所有房间。当访问到第 i 个房间时,如果生命值小于等于 0,那么我们必须要对房间顺序进行调整:

显然选择第 i 个房间之后的房间是没有意义的,它并不会改变当前的生命值;

因此我们只能选择第 i 个房间及之前的房间。对于所有可选的房间,无论将哪个房间调整至末尾,都不会改变最终的生命值(因为数组 nums 的和不会变化)。由于我们希望调整的次数最少,因此应当贪心地选择最小的那个 numsj 调整至末尾,使得当前的生命值尽可能高。

算法

在遍历房间的过程中,如果 numsi 为负数,我们将其放入一个小根堆(优先队列)中。当计算完第 i 个房间的生命值影响后,如果生命值小于等于 0,那么我们取出堆顶元素,表示将该房间调整至末尾,并将其补回生命值中。由于一定会从小根堆中取出一个小于等于 numsi 的值,因此调整完成后,生命值一定大于 0。

当所有房间遍历完成后,我们还需要将所有从堆中取出元素的和重新加入生命值,如果生命值小于等于 0,说明无解。

参考代码

java 复制代码
class Solution {
    public int magicTower(int[] nums) {
        // 建立小根堆,使得每次取都取最小值
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        int ans = 0;            // 记录调整次数
        long hp = 1, delay = 0; // 记录当前血量 和 延迟掉血量

        // 从头开始遍历
        for(int i = 0; i < nums.length; i++) {
            // 遇到正数,血量直接相加
            if(nums[i] > 0) {
                hp += nums[i];
            // 遇到负数相加之后,血量相加,将负数血量放到小根堆
            } else if(nums[i] < 0) {
                hp += nums[i];
                pq.offer(nums[i]);
                // 看是否比0小,如果小于0,将之前最大的负数放到后面
                if(hp <= 0) {
                    ans++;
                    int curr = pq.poll();
                    hp -= curr;
                    delay += curr;
                }
            }
        }
        hp += delay;
        return hp <= 0 ? -1 : ans;
    }
}
相关推荐
郝学胜-神的一滴7 分钟前
C++20 高级编程 004:从初始化、内存到const系列关键字
开发语言·算法·编程·软件构建·c++20
kyle~13 分钟前
点云配准--- 迭代最近点 ICP 求解
线性代数·算法·机器学习
qq74223498423 分钟前
Gradio 极简入门:三分钟为AI模型打造交互界面,并对比Streamlit与Dash如何选型
人工智能·算法·大模型·交互·dash
1000世界小札6 小时前
《大话数据结构》第9章精读:归并排序与快速排序完整 C++ 实现
数据结构·c++·算法
2601_956121979 小时前
背包基础篇(01、完全、分组、多重、混合)
c++·算法·动态规划
兴通物联科技10 小时前
SMT PCB 微小 DataMatrix 码扫不动问题分析 兴通 XT8601B 600 万像素工业读码器落地实践
大数据·人工智能·单片机·嵌入式硬件·算法·计算机视觉
月华路13 小时前
G1 GC 对数组与大对象(Humongous)的处理
java·jvm·算法
我想走路带风13 小时前
LRU和最长前缀和(计算机网络算法)
计算机网络·算法
M78佐菲13 小时前
Linux学习笔记:进程
linux·笔记·学习·算法