LeetCode-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 。
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 400
相似题目
题解分析
解法一:动态规划
- 本题就是一个经典的动态规划题,当前状态依赖到前面的状态。
- 假设dp[i]表示以第i天为结束日期,小偷能够偷到的最大金额。
- 状态转移方程可以定义为:dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
class Solution {
public int rob(int[] nums) {
int n = nums.length;
int[] dp = new int[n]; // dp[i]表示以i结尾的这天,小偷可以偷到的最大金额
dp[0] = nums[0];
for(int i=1; i<n; i++){
if(i > 1){
dp[i] = Math.max(dp[i-2] + nums[i], dp[i-1]);
}else{
dp[i] = Math.max(dp[i-1], nums[i]);
}
}
return dp[n-1];
}
}
解法二:动态规划压缩数组
- 考虑到是动态规划,而且当前状态只依赖于之前的状态。
- 与以前传统的压缩数组不同的是,当前状态依赖于之前和之前之前的状态,所以这里需要设置两个变量来存储之前的两个状态。
class Solution {
public int rob(int[] nums) {
int n = nums.length;
// dp[i]表示以i结尾的这天,小偷可以偷到的最大金额
int dp = 0, pre = 0;
for(int i=1; i<=n; i++){
int temp = dp;
dp = Math.max(dp, pre + nums[i-1]);
pre = temp;
}
return dp;
}
}
Either Excellent or Rusty
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了