力扣热门算法题 174. 地下城游戏,189. 轮转数组,198. 打家劫舍

174. 地下城游戏,189. 轮转数组,198. 打家劫舍,每题做详细思路梳理,配套Python&Java双语代码, 2024.03.31 可通过leetcode所有测试用例。

目录

174. 地下城游戏

解题思路

完整代码

Python

Java

189. 轮转数组

解题思路

完整代码

Python

Java

198. 打家劫舍

解题思路

完整代码

Python

Java


174. 地下城游戏

        恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m * n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。

        骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。

        有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。

为了尽快解救公主,骑士决定每次只 向右 或 向下 移动一步。

返回确保骑士能够拯救到公主所需的最低初始健康点数。

        注意:任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。

示例 1:

输入:dungeon = [[-2,-3,3],[-5,-10,1],[10,30,-5]]
输出:7
解释:如果骑士遵循最佳路径:右 -> 右 -> 下 -> 下 ,则骑士的初始健康点数至少为 7 。

示例 2:

输入:dungeon = [[0]]
输出:1

解题思路

恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。

骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。

有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。

为了尽快解救公主,骑士决定每次只 向右 或 向下 移动一步。

返回确保骑士能够拯救到公主所需的最低初始健康点数。

注意:任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。

示例 1:

输入:dungeon = [[-2,-3,3],[-5,-10,1],[10,30,-5]]
输出:7
解释:如果骑士遵循最佳路径:右 -> 右 -> 下 -> 下 ,则骑士的初始健康点数至少为 7 。

示例 2:

输入:dungeon = [[0]]
输出:1

完整代码

Python
class Solution:
    def calculateMinimumHP(self, dungeon: List[List[int]]) -> int:
        m, n = len(dungeon), len(dungeon[0])
        dp = [[float('inf')] * (n + 1) for _ in range(m + 1)]
        dp[m][n - 1] = dp[m - 1][n] = 1

        for i in range(m - 1, -1, -1):
            for j in range(n - 1, -1, -1):
                min_health = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]
                dp[i][j] = max(1, min_health)

        return dp[0][0]
Java
class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        int m = dungeon.length, n = dungeon[0].length;
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 0; i <= m; ++i) Arrays.fill(dp[i], Integer.MAX_VALUE);
        dp[m][n - 1] = dp[m - 1][n] = 1;

        for (int i = m - 1; i >= 0; --i) {
            for (int j = n - 1; j >= 0; --j) {
                int minHealth = Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j];
                dp[i][j] = Math.max(1, minHealth);
            }
        }

        return dp[0][0];
    }

}

189. 轮转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

解题思路

解决这个问题的关键在于找到一种高效的方法来旋转数组,而不仅仅是简单地执行 k 次单步旋转。一种有效的方法是通过反转数组的部分来实现旋转效果。具体步骤如下:

  1. 反转整个数组:首先,将整个数组反转。这一步会将原本应该被移动到数组前面的元素移动到数组的后面。

  2. 反转数组的前 k 个元素:接着,反转数组中前 k 个元素。由于数组已经被整体反转过,这一步实际上是将那些应该位于数组前面的元素放到了正确的位置。

  3. 反转数组剩余部分:最后,反转数组中剩余的部分,即从索引 k 到数组结束的部分。这一步是将剩余的元素放到它们应该在的位置。

注意   由于 k 可能大于数组的长度,所以在进行操作之前需要将 k 对数组长度取模,以确保 k 在数组长度范围内。

完整代码

Python
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        n = len(nums)
        k %= n

        def reverse(start, end):
            while start < end:
                nums[start], nums[end] = nums[end], nums[start]
                start, end = start + 1, end - 1

        reverse(0, n - 1)
        reverse(0, k - 1)
        reverse(k, n - 1)
Java
class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k %= n;

        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, n - 1);
    }

    private void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }

}

198. 打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 1:

输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。

示例 2:

输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。

解题思路

这个问题可以通过动态规划(Dynamic Programming, DP)来解决。我们可以定义一个一维数组 dp,其中 dp[i] 表示到达第 i 个房屋时能偷窃到的最高金额,注意这里的 i 是从 0 开始的索引。

解题步骤如下:

  1. 基本情况:当只有一间房屋时(即数组长度为 1),那么偷窃到的最高金额就是这间房屋中的金额。所以 dp[0] = nums[0](如果数组不为空)。

  2. 第二间房屋:当有两间房屋时,由于不能同时偷窃相邻的房屋,因此偷窃到的最高金额是这两间房屋中金额较大的那一个。所以 dp[1] = max(nums[0], nums[1])

  3. 状态转移方程:对于第 i 间房屋(i > 1),有两种选择:

    • 不偷窃第 i 间房屋,那么最高金额为到达前一间房屋时的最高金额,即 dp[i-1]
    • 偷窃第 i 间房屋,那么由于不能偷窃相邻的房屋,最高金额为第 i-2 间房屋的最高金额加上第 i 间房屋中的金额,即 dp[i-2] + nums[i]

    因此,状态转移方程为 dp[i] = max(dp[i-1], dp[i-2] + nums[i])

  4. 结果:数组 nums 中最后一个房屋的索引为 nums.length - 1,所以 dp[nums.length - 1] 就是不触动警报装置情况下能偷窃到的最高金额。

完整代码

Python
class Solution:
    def rob(self, nums: List[int]) -> int:
        if not nums:
            return 0
        if len(nums) == 1:
            return nums[0]

        dp = [0] * len(nums)
        dp[0], dp[1] = nums[0], max(nums[0], nums[1])

        for i in range(2, len(nums)):
            dp[i] = max(dp[i-1], dp[i-2] + nums[i])

        return dp[-1]
Java
class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        if (nums.length == 1) {
            return nums[0];
        }
        
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        
        for (int i = 2; i < nums.length; i++) {
            dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
        }
        
        return dp[nums.length - 1];
    }

}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/512757.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python中输出显示台的设置

效果: 前言 这种文字显示的方式很适合新手来学习,毕竟新手还学不到pygame做游戏的, Python入门我们一般都学的是输入输出的游戏,但是如果加上一些文字和背景的改善可能会更好. 如何改变字体颜色 字体颜色(跟他的变量名是一样的): #改变字体颜色 RED \033[91m GREEN \033…

kettle介绍-Step之加密及解密

加密 进入kettle的安装目录 cd /d D:\Application\pdi-ce-6.0.0.0-353\data-integration windows系统命令行执行&#xff1a;Encr.bat -kettle 123 cd /data/data-integration linux/mac系统命令行执行&#xff1a;encr.sh -kettle 123 可生成Encrypted 2be98afc86aa7f2e4cb79…

zabbix绑定钉钉进行通知,网页端添加JavaScript,无脑式操作

文章目录 前言一、编辑zabbix告警JavaScript脚本二、代码如下:编辑消息模板,自定义markdown格式的消息。总结前言 随着人工智能的不断发展,zabbix监控这门技术也越来越重要,一下进入正题。 一、编辑zabbix告警JavaScript脚本 没有没接可以新增媒介 其中URL是你的机器人地…

2024最新软件测试【测试理论+ 抓包与网络协议】面试题(内附答案)

一、测试理论 3.1 你们原来项目的测试流程是怎么样的? 我们的测试流程主要有三个阶段&#xff1a;需求了解分析、测试准备、测试执行。 1、需求了解分析阶段 我们的 SE 会把需求文档给我们自己先去了解一到两天这样&#xff0c;之后我们会有一个需求澄清会议&#xff0c; …

stm32 HAL中断GPIO——1

1选择引脚为中断 中断详细配置 1 模式选择 上拉下拉 再点击NVIC可进行分组 再勾选如图 总结步骤 1选择中断 2配置时钟//选择外部时钟 3配置模式 4勾选NVIC

Python实现【贪吃蛇大作战】+源码

文章目录 前言&#xff1a;一、游戏概述1.游戏玩法2.游戏特色 二、游戏规则三、工具选择四、主要技术pygame 库numpy 库cocos2d 五、源码分享六、项目地址 前言&#xff1a; 今天的GitHub小游戏分享&#xff0c;我们将聚焦于一个经典而又极富趣味性的游戏——贪吃蛇大作战。这…

【C++】二分查找算法(模板)

重点 只需要记住两点&#xff1a; 1.left right 时&#xff0c;一定就是最终结果&#xff08;包括找不到目标值&#xff09;&#xff0c;无需再次判断&#xff0c;如果判断就会死循环 2.求中点如果是求左端点 mid left (right - left)/2 如果是求右端点 mid left (right -…

【Python项目】AI动物识别工具

目录 背景 技术简介 系统简介 界面预览 背景 成像技术在全球科技发展中扮演了关键角色。在科学研究领域&#xff0c;拍摄所得的图像成为了一种不可或缺的研究工具。特别是在生态学与动物学研究中&#xff0c;鉴于地球的广阔地域和多样的气候条件&#xff0c;利用图像技术捕…

关于我20系列显示安装cuda11.8版本一直还报找不到nvcc.exe的这档子事

这几天研究3d gaussian&#xff08;3d高斯&#xff09; 由于本人电脑还是五年前的20系列显卡&#xff0c;本身还是支持cuda的&#xff0c;就没想那么多&#xff0c;结果处处踩坑处处踩雷&#xff0c;在研究2天国内资料翻遍了的情况下&#xff0c;终于去外面看老外发了一个chec…

arm的状态寄存器

目录 一、arm 的 PSRs二、CPSR2.1 CPSR_cxsf 三、SPSR四、APSR 一、arm 的 PSRs arm 中有很多程序状态寄存器&#xff08;Program Status Registers&#xff0c;PSRs&#xff09;用于存储处理器的状态信息&#xff0c;包括 CPSR\SPSR\FPSR\APSR 等&#xff1a; CPSR&#xff…

九州金榜家庭教育孩子沉迷手机网络怎么办?

孩子沉迷于手机网络的问题&#xff0c;在当今社会已变得日益严重。手机网络的普及使得孩子们过早地接触到了虚拟世界&#xff0c;而长时间沉浸其中不仅影响他们的学业&#xff0c;还可能对他们的身心健康造成危害。那么&#xff0c;面对这一问题&#xff0c;家长应该如何应对呢…

数字人视频合成平台推荐

数字人讲解视频和全景作品的结合是一种全新的数字交互方式&#xff0c;可为用户提供更加直观和具有沉浸感的内容展示和交互体验&#xff0c;从而适用于诸如旅游、展览、博物馆、教育培训、泛房地产、以及娱乐和文化等应用场景。 当前数字人合成视频技术已经发展至日益成熟的阶…

Oracle基础-PL/SQL编程 备份

1、PL/SQL简介 PL/SQL块结构 约定&#xff1a;为了方便&#xff0c;本文后面把PL/SQL简称PL。 PL程序都是以块&#xff08;BLOCK&#xff09;为基本单位&#xff0c;整个PL块分三部分&#xff1a;声明部分&#xff08;使用DECLARE开头&#xff09;、执行部分(以BEGIN开头)和异…

武汉星起航:跨境电商优势尽显,引领全球贸易与文化交流新浪潮

在全球化日益加深的今天&#xff0c;跨境电商行业以其独特的优势和好处&#xff0c;逐渐超越了国内电商行业&#xff0c;成为了电商领域的新宠。跨境电商不仅拓展了企业的市场范围&#xff0c;还为消费者带来了更多选择和便利。武汉星起航认为与国内电商相比&#xff0c;跨境电…

5032温补晶振的一些常用型号和实例应用

5032晶振是常用的一种尺寸的晶振&#xff0c;而5032温补晶振因为其高精度高稳定性而被广泛应用。小尺寸封装5.0mm*3.2mm*1.45mm&#xff0c;非常节省空间&#xff0c;便于设计与使用。其实爱普生推出了一系列的5032温补晶振:以TG5032CAN、TG5032SAN、TG5032CDN、TG5032SDN&…

IDEA一行代码出现下划实线,怎么处理?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

【Qt】使用Qt实现Web服务器(九):EventSource+JSON实现工业界面数据刷新

1、效果 效果如下,实时刷新温度、湿度 2、源码 2.1 index.html <html><body> <!-- 页面布局,本人对HTML标签不熟悉,凑合看吧 --> <div><label for

整顿编剧市场:程序员提交测试流程的最佳实践

讲动人的故事,写懂人的代码 最近,一部去年推出的国产电视剧在IT圈子里引起了轰动。 引起关注的原因,并非剧中程序员的外形出众,而是她提交代码测试的方式——将写有代码的纸张放入文件夹,然后递给了对面的测试人员。如图1所示。 图1 程序员将写有代码的纸张放入文件夹,并…

2024年全新靠谱的FTP替代升级解决方案

随着企业规模的扩大和业务的多元化&#xff0c;传统的TCP协议在数据传输效率上逐渐显现出局限性。TCP协议虽然以其稳定性和可靠性被广泛应用&#xff0c;但在面对大规模数据传输时&#xff0c;其性能瓶颈逐渐成为企业发展的阻碍。同时&#xff0c;基于TCP的应用协议如Telnet、F…

JS两道题:判断这个月有几天;计算薪资缴税。

计算的时候直接在字符串模版中没问题的&#xff1a; swicth语句分支结构&#xff1a;&#xff08;很多不一样的固定值&#xff09; break结束当前穿透现象 他它的表达式的结果和值必须是全等的关系 当所有的值都不匹配的时候就执行这个部分代码 其实就是在考察条件问题。比如&…