【DP】LeetCode 213. 打家劫舍 II

题目链接

213. 打家劫舍 II

思路

分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律

在数组的动态规划问题中,一般 dp[i] 都是表示以 nums 以前 i 个元素组成(即 nums[i - 1])的状态;dp[i][j] 分别表示以 nums1 前 i 个元素(即 nums1[i - 1])组成和以 nums2 前 j 个元素(即 nums2[j - 1])组成的状态,以此类推

字符串也是个数组,是字符数组

表示状态

状态表示就是靠猜,但是会有猜的套路,一般都是通过最终结果和数组数量来猜

这个题和【DP】LeetCode 198. 打家劫舍十分相似,唯一的区别就是在首尾房子的选择上,这时候可以分为三种情况讨论:

  1. 打劫第一间房
  2. 打劫最后一间房
  3. 首尾两间都不打劫

如下图所示

image

图片来自labuladong

实际上第三种情况肯定是小于等于前面两种情况的,因为它的可选择性最少,不可能得出最大值,所以只需要判断前面两种情况取最大值即可。

定义 dp[i][j] 表示在情况 i 的状况下,前 j 个房间能打劫到的最大值。

找状态转移方程

思考的方向是:大问题的最优解怎么由小问题的最优解得到

与198题相似

dp[i][j]=max(dp[i][j1],dp[i][j2]+nums[j1])

边界处理

这一部分是本题最需要注意的点,因为两个遍历的起始点不同,所以初值设置也要单独考虑

dp[0][1] = nums[0];
dp[1][2] = nums[1];

代码

dp数组版

class Solution {
    public int rob(int[] nums) {
        int n = nums.length;
        if(n == 1){
            return nums[0];
        }

        // dp[0] 求 nums[0 : n - 2] 的最大值
        // dp[1] 求 nums[1 ; n - 1] 的最大值
        int[][] dp = new int[2][n + 1];

        dp[0][1] = nums[0];
        dp[1][2] = nums[1];
        for(int i = 2; i < n; i++){
            dp[0][i] = Math.max(dp[0][i - 1], dp[0][i - 2] + nums[i - 1]);
        }
        for(int i = 3; i <= n; i++){
            dp[1][i] = Math.max(dp[1][i - 1], dp[1][i - 2] + nums[i - 1]);
        }

        return Math.max(dp[0][n - 1], dp[1][n]);
    }
}
posted @   Frodo1124  阅读(30)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示