力扣刷题 - LCP 30. 魔塔游戏

该博客讨论了一道关于调整访问房间顺序以保持血量正数的算法问题。在魔塔游戏中,小扣需要按顺序经过各房间,每个房间对血量有增减影响。题目要求找到最小调整次数使小扣能完成所有房间的访问。解决方案是利用优先队列,将负数房间按数值大小排序,当血量不足时调整最小负数房间至末尾。示例展示了具体实现和思路,帮助理解如何解决此类问题。
摘要由CSDN通过智能技术生成

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

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

示例 1:

输入:nums = [100,100,100,-250,-60,-140,-50,-50,100,150]
输出:1
解释:初始血量为 1。至少需要将 nums[3] 调整至访问顺序末尾以满足要求。

示例 2:

输入:nums = [-200,-300,400,0]
输出:-1
解释:调整访问顺序也无法完成全部房间的访问。

提示:

  • 1 <= nums.length <= 10^5
  • -10^5 <= nums[i] <= 10^5
分析一下题目:
首先 N 个房间   0 - N-1,房间可能补血可能扣血(正数补血  负数扣血);
还有就是 初始血量1 无上限 ,每次仅能将一个负数房间调整到访问的末尾;
最后让我们求最少需要调整多少次才能顺利访问所有房间,无法访问所有房间返回 -1;

情景型的问题,分析一下,这道题其实不是很难,只要我们抓住一个点,正数补血,负数扣血
而我们需要调整 负数房间 的临界点就是 当我们的血量 <= 0 的时候,我们必须要调整了,
毕竟再不调整就结束了,我们调整的策略是什么呢?当然是想要调整的值越小越好啦。

首先我们要利用的是 队列 的特性,先进先出,并且我们希望小的在前面,所以我们使用了
PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2) -> o1 - o2);
class Solution {
    public int magicTower(int[] nums) {
        PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2) -> o1 - o2);
        long res = 0,cur = 1,sum = 0;
        // 求和
        for(int x:nums){
            sum += x;
        }
        // 不可能到达所有房间
        if(sum < 0){
            return -1;
        }
        for(int x:nums){
            cur += x;
            if(x < 0){
                //入列
                queue.offer(x);
            }
            // 当前血量值小于或等于0
            if(cur <= 0){
                 // 出列 调整负数的位置 相当于补血
                cur -= queue.poll();
                // 记录调换次数
                res++;
            }
        }
        return (int)res;
    }
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TyuIn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值