1. 题目
读题
https://leetcode.cn/problems/house-robber/
考查点
这道题的考查点是动态规划的基本思想和应用,
- 即如何将一个复杂的问题分解成更小的子问题,
- 如何找到问题的状态和状态转移方程,
- 如何确定问题的边界条件和初始值,
- 以及如何用代码来实现动态规划的算法。
2. 解法
思路
一个可能的解决方案是使用一个一维数组dp来存储每个房屋的最大收益,
dp[i]表示从第0个房屋到第i个房屋能够偷窃的最大金额。
那么对于每个房屋,
我们有两种选择:偷或者不偷。
如果我们偷第i个房屋,那么我们不能偷第i-1个房屋,所以dp[i] = dp[i-2] + nums[i]。
如果我们不偷第i个房屋,那么我们可以偷第i-1个房屋,所以dp[i] = dp[i-1]。
我们要取这两种情况的较大值,所以dp[i] = max(dp[i-1], dp[i-2] + nums[i])。
代码逻辑
我可以用以下的步骤来描述代码的逻辑:
- 首先,我检查输入的数组是否为空或者长度为0,如果是,就直接返回0,因为没有房屋可以偷窃。
- 其次,我检查输入的数组的长度是否为1,如果是,就直接返回数组的第一个元素,因为只有一间房屋可以偷窃。
- 然后,我创建一个一维数组dp来存储每个房屋的最大收益,数组的长度和输入的数组相同。我初始化dp[0]为nums[0],dp[1]为nums[0]和nums[1]中的较大值。
- 接着,我从第2个房屋开始遍历输入的数组,对于每个房屋,我用状态转移方程来更新dp[i],即dp[i] = max(dp[i-1], dp[i-2] + nums[i])。
- 最后,我返回dp[n-1]作为最终结果,其中n是输入数组的长度。
具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class Solution { public int rob( int [] nums) { // 边界条件 if (nums == null || nums.length == 0 ) { return 0 ; } if (nums.length == 1 ) { return nums[ 0 ]; } // 创建dp数组 int n = nums.length; int [] dp = new int [n]; // 初始化 dp[ 0 ] = nums[ 0 ]; dp[ 1 ] = Math.max(nums[ 0 ], nums[ 1 ]); // 遍历 for ( int i = 2 ; i < n; i++) { // 状态转移方程 dp[i] = Math.max(dp[i- 1 ], dp[i- 2 ] + nums[i]); } // 返回结果 return dp[n- 1 ]; } } |
3. 总结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2019-05-01 java中的12种锁
2019-05-01 公平锁与非公平锁
2019-05-01 设计模式:门面模式(Facade)
2019-05-01 设计模式:装饰者模式
2019-05-01 设计模式:组合模式
2019-05-01 设计模式:桥接模式
2019-05-01 设计模式:适配器模式(Adapter)