代码随想录算法训练营第四十八天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

2023-05-16

文章目录

      • 198.打家劫舍
      • 213.打家劫舍II
      • 337.打家劫舍III

198.打家劫舍

  • 题目链接:代码随想录

  • 解题思路:
    1.dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i] 只是考虑,不一定偷
    2.递推公式:dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]),根据选不选i位置,由两个方面推导而来
    3.dp数组如何初始化。因为递推公式是dp[i-1]和dp[i-2],所以初始化要考虑dp[0]和dp[1]
    因为要取最大值,所以dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1])
    4.遍历顺序:从前向后。因为后面状态由前面推出来

public int rob(int[] nums) {

    if(nums.length == 1){
        return nums[0];
    }

    //1.定义dp数组,dp数组表示dp[i],考虑i位置的情况下能打劫到的最大价值
    //这里dp[i]中的i代表不一定选第i个位置的数字
    int[] dp = new int[nums.length];

    //2.初始化
    dp[0] = nums[0];
    dp[1] = Math.max(nums[0], nums[1]);
    //3.遍历
    for (int i = 2; i < dp.length; i++) {
        //根据选不选i位置的数值
        //选,只能加上dp[i-2]的数值
        dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
    }

    //4.最后返回递推的结果
    return dp[nums.length - 1];
}

213.打家劫舍II

关键点:将环形问题的情况分解成线性问题的情况,进而求解

  • 题目链接:代码随想录

  • 解题思路:
    ①根据环形问题,分为三种情况一种不考虑首尾,一种考虑首不考虑尾,最后一种考虑尾不考虑首
    后两种情况考虑首不考虑尾就包含了不考虑首尾的问题,因此只用将最后两种打家劫舍问题求一个和即可
    编写一个有参数的打家劫舍函数,里面进行初始化和相应范围的打家劫舍问题的分析。
    要想编写容易,要借用自动扩容的ArrayList数组,dp范围和nums范围和位置一致

  • 三种状态

    Snipaste_2023-05-01_21-51-56 Snipaste_2023-05-01_21-52-06 Snipaste_2023-05-01_21-52-22
public int rob(int[] nums) {
    int len = nums.length;
    //保证len从3开始
    if(len == 1){
        return nums[0];
    }
    if(len == 2){
        return Math.max(nums[0], nums[1]);
    }

    return Math.max(robAction(nums, 0, len - 2),robAction(nums, 1, len - 1));

}

/**
     * 考虑[start,end]位置房屋的打家劫舍问题
     * @param nums
     * @param start
     * @param end
     * @return
     */
private int robAction(int[] nums, int start, int end) {
    //定义dp数组的时候,要选用可扩容的ArrayList,因为要保证dp数组下标值和nums数组下标值一样
    List<Integer> dp = new ArrayList<>(nums.length);
    for(int i = 0;i < dp.size();i++){
        dp.add(0);
    }
    //初始化
    dp.set(start, nums[start]);
    dp.set(start + 1, Math.max(nums[start], nums[start + 1]));
    for (int i = start + 2; i <= end; i++) {
        dp.set(i, Math.max(dp.get(i - 2) + nums[i], dp.get(i - 1)));
    }

    return dp.get(end);
}
public static void main(String[] args) {
    List<Integer> dp = new ArrayList<>(2);
    System.out.println(dp.size());//0  这里只有首次添加元素之后,size1才变化
    dp.add(0, 0);
    System.out.println(dp.size());//1
}

337.打家劫舍III

本题是树形dp的入门级别的题目,通过返回dp数组来保存遍历状态 也称状态标记递归,通过一个标记,来记录遍历过程中的最大值

  • 题目链接:代码随想录

  • 解题思路:
    1.确定递归函数的参数和返回值
    那么返回值就是一个长度为2的dp数组。dp[0]表示不偷当前节点情况下的金钱dp[1]偷当前节点情况下的金钱,参数为当前节点,将当前节点偷与不偷得到的金钱返回给上一层
    在递归过程中,系统栈会保存每一层递归的参数,因此每一个节点的dp数组经过分析汇聚给root
    2.终止条件
    遇到空节点,直接返回本层偷的结果{0,0}
    3.确定遍历顺序:
    采用后序遍历,因为要根据左右节点的偷的金钱状态,根节点判断当前根偷还是不偷
    这种需要依靠状态的,都需要采取后序遍历
    4.确定单层递归逻辑:
    如果偷当前节点,那么dp[1] = root.val + 左右节点不偷的金钱
    如果不偷当前节点,那么左右节点可以偷,也可以不偷,因此dp[0] = max([0],[1])(左右节点)

  • 推导过程:

    Snipaste_2023-05-01_23-34-31
public int rob(TreeNode root) {
    int[] dp = robAction1(root);

    return Math.max(dp[0], dp[1]);
}


/**
     * 递归树
     * @param root
     * @return 一个dp一维数组
     */
private int[] robAction1(TreeNode root){
    //本层dp状态数组
    int[] dp = new int[2];
    //终止条件
    if(root == null){
        return dp;
    }

    int[] leftDp = robAction1(root.left);
    int[] rightDp = robAction1(root.right);

    //本根不偷
    dp[0] = Math.max(leftDp[0], leftDp[1]) + Math.max(rightDp[0], rightDp[1]);
    //本根偷
    dp[1] = root.val + leftDp[0] + rightDp[0];

    //返回本层偷与不偷的状态
    return dp;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代码随想录算法训练营第四十八天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍III 的相关文章

  • (c语言)初识结构体

    目录 1 结构体的声明 1 1 结构的基础知识 1 2 结构的声明 1 3 结构成员的类型 1 4 结构体变量的定义和初始化 2 结构体成员的访问与传参 1 结构体的声明 1 1 结构的基础知识 结构是一些值的集合 xff0c 这些值称为成
  • (修炼内功)函数栈帧的创建和销毁

    前言 修炼内功才是你和别人拉开差距的地方 越触及底层就会发现计算机竟有如此的有魅力 希望每个看到这篇文章的人都可以好好食用 目录 前言 1 什么是函数栈帧 2 理解函数栈帧能解决什么问题呢 xff1f 3 函数栈帧的创建和销毁解析 3 1
  • 调试技巧总结

    目录 1 调试是什么 xff1f 2 调试的基本步骤 3 Debug和Release的介绍 4 调试实例 4 1 实现代码 xff1a 求 1 xff01 43 2 xff01 43 3 xff01 43 n xff1b 不考虑溢出 4 2

随机推荐

  • 一篇文章带你弄懂数据的存储(C语言)

    前面我们已经初步了解了数据类型 xff0c 接下来我们就详细来学习进阶的数据存储 目录 1 类型的基本归类 2 分析两种数据类型的取值范围 3 大小端 大小端字节序存储 介绍 3 1什么大端小端 xff1a 3 2 为什么有大端和小端 3
  • (万字详解)指针进阶

    前面博客已经更新了初阶的指针 xff0c 接下来我们来详细地学习进阶指针的内容 目录 1 字符指针 2 指针数组 3 数组指针 3 1 数组指针的定义 3 2 amp 数组名VS数组名 3 3 数组指针的使用 4 数组参数 指针参数 4 1
  • c语言题目总结

    前言 xff1a 自己刷题过程中的错题本 xff0c 后续会一直更新 目录 1 输入一个班级5个学生各5科成绩 xff0c 输出5个学生各5科成绩及总分 2 实现字母的大小写转换 多组输入输出 3 能把函数处理结果的二个数据返回给主调函数
  • (c语言)万字详解字符函数,字符串函数,内存函数--内含所有模拟实现方法

    目录 前言 1 字符串操作函数 1 1 strlen 1 1 1 字符串以 39 0 39 作为结束标志 xff0c strlen函数返回的是在字符串中 39 0 39 前面出现的字符个数 xff08 不包含 39 0 39 1 1 2 参
  • ubuntu16.04开机登录后蓝屏

    ubuntu16 04 3 64bit 昨晚更新了内核 xff0c 然后在软件中心点了更新全部 xff0c 进度条没动过 xff0c 退出后shutdown xff0c 然后今早起来发现登录进去后桌面一片蓝 xff0c 图形界面gg了 xf
  • 数学分析(4): 函数的连续性

    连续性的概念 为了引入函数连续性的多种定义 xff0c 我们记 x为x的增量 定义一 xff1a 函数在一点上连续性定义 xff08 极限 xff09 设函数f在某U x0 内有定义 xff0c 若limx gt x0f x 61 f x0
  • PHP脚本执行超时的解决办法

    在php中默认脚本执行超时时间为30秒了 xff0c 如果你未进行设置30秒之后如果你的脚本还未执行完就会超时了 xff0c 下面我来给大详解解决PHP脚本执行超时的方法 php ini 中缺省的最长执行时间是 30 秒 xff0c 虽然可
  • 类和对象(一)

    目录 1 目标 xff1a 理解类和对象之间的关系 2 面向对象的初步认知 2 1 什么是面向对象 2 2 面向对象与面向过程 3 类的定义和使用 3 1 类的定义格式 4 类的实例化 4 1 什么是实例化 5 this引用 5 1 为什么
  • Java语言数据类型与c语言数据类型的不同

    目录 一 c语言数据类型 1 基本类型 xff1a 2 枚举类型 xff1a 3 空类型 xff1a 4 派生类型 xff1a 二 C语言编程需要注意的64位和32机器的区别 三 不同之处 一 c语言数据类型 首先 xff0c 先来整体介绍
  • 【代码源】每日一题 添加括号

    2022 05 06 题目链接 xff1a 添加括号 题目 Daimayuan Online Judge 题目描述 xff1a 现在给出一个表达式 xff0c 形如 a1 a2 a3 an 如果直接计算 xff0c 就是一个个除过去 xff
  • 【数据结构】顺序表

    目录 1 前言 2 线性表 3 顺序表 3 1 概念及结构 3 2 接口实现 1 顺序表初始化 2 顺序表销毁 3 检查空间并扩容 4 顺序表尾插 5 顺序表头插 6 顺序表尾删 7 顺序表头删 8 顺序表查找 9 顺序表在pos位置插入x
  • 如何python代码打包成可执行的.exe文件

    首先 xff0c 需要有pyinstaller库 xff0c 没有的可以打开win 43 R后输入cmd xff0c 打开界面如下 xff1a 直接使用pip命令 xff0c 输入 pip install pyinstaller 即可下载该
  • #C语言 输入10个整数,查找并删除重复的数字,打印结果。

    萌新做题 xff0c 以下为本人拙见 xff0c 若某位高人另有高招 xff0c 还望分享 VS2013 define CRT SECURE NO WARNINGS include lt stdio h gt define N 10 voi
  • Linux安装mysql遇到Error: libssl.so.10或libssl.so5问题的解决

    今天linux里安装mysql遇到的问题 很遗憾finallshell重启了 xff0c 我也懒得重新弄成报错 xff0c 弄报错截图了 xff08 手动狗头 xff09 报错类似于 xff1a mysql error while load
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素

    704 二分查找 题目链接 leetcode 思路 设置一个指向中心位置的标识和两个左右指针 当左右指针符合正常顺序时 xff0c 比较中心位置元素与目标元素值大小 xff0c 根据大小适时更新中心位置标识 span class token
  • 项目笔记-瑞吉外卖

    文章目录 1 业务开发day011 软件开发整体介绍2 项目整体介绍 star 3 开发环境搭建4 登录功能 xff1a star4 1代码实现 5 退出功能6 页面效果出现 1 业务开发 day01 1 软件开发整体介绍 2 项目整体介绍
  • 2.黑马SpringbBoot运维篇笔记自己修改

    SpringBoot运维实用篇 基础篇发布以后 xff0c 看到了很多小伙伴在网上的留言 xff0c 也帮助超过100位小伙伴解决了一些遇到的问题 xff0c 并且已经发现了部分问题具有典型性 xff0c 预计将有些问题在后面篇章的合适位置
  • (三)Python-tkinter-pyinstaller项目之EXE打包器(项目展示版)

    由于网上只讲述原理的文章太多 xff0c 怎么使用的文章太少 xff0c 所以本人文章只负责展示效果及代码注释 xff0c 不着重讲解原理 Python tkinter pyinstaller项目之EXE打包器 一 前言二 建立根窗口三 添
  • 代码随想录算法训练营第四十五天|70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数

    文章目录 70 爬楼梯 xff08 进阶 xff09 322 零钱兑换279 完全平方数 今天的题一道是求装满背包的可能情况 另两道都是求装满背包的所需的最小物品数目 xff0c 不用考虑是组合还是排序问题 70 爬楼梯 xff08 进阶
  • 代码随想录算法训练营第四十八天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍III

    文章目录 198 打家劫舍213 打家劫舍II337 打家劫舍III 198 打家劫舍 题目链接 xff1a 代码随想录 解题思路 xff1a 1 dp i xff1a 考虑下标i xff08 包括i xff09 以内的房屋 xff0c 最