动态规划之打家劫舍

article/2025/9/12 18:10:13

动态规划之打家劫舍

文章目录

  • 动态规划之打家劫舍
    • 1. "198. 打家劫舍"
    • 2. "198. 打家劫舍(变种:输出路径)"
    • 3. "213. 打家劫舍 II"
    • 4. "337. 打家劫舍 III"

1. “198. 打家劫舍”

在这里插入图片描述

dp数组定义:dp[i]代表偷窃0~i号房屋所能获得的最大金额
递推公式:偷窃0~i号房屋所能获得的最大金额也就是要么偷窃i号房屋,那么他只能偷窃i号房屋前面的前面的房屋,也就是dp[i-2]+nums[i],
要么不偷窃i号房屋,那么他可以偷窃i前面的房屋,也就是dp[i-1]
因此递推公式为dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
初始化:需要考虑偷窃第一号房屋和第二号房屋的最大金额
只能偷窃第一号房屋,最大金额肯定为nums[0]
只能偷窃第一号房屋和第二号房屋,若想获得最大金额,只能从一号房屋和二号房屋中选金额最大的

class Solution {public int rob(int[] nums) {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];}
}

2. “198. 打家劫舍(变种:输出路径)”

class Solution {public List<Integer> rob(int[] nums) {if (nums.length == 1) {return nums[0];}int[][] dp = new int[nums.length][2];dp[0][0] = 0;dp[0][1] = nums[0];dp[1][0] = nums[0];dp[1][1] = nums[1];for (int i = 2; i < nums.length; i++) {dp[i][0] = dp[i - 1][1];dp[i][1] = Math.max(dp[i - 2][1] + nums[i], dp[i - 2][0] + nums[i]);}int target = Math.max(dp[nums.length - 1][0],dp[nums.length - 1][1]);List<Integer> track = new ArrayList<>();for (int i = nums.length - 1; i >= 0; i--) {if (dp[i][1] == target) {target = target - nums[i];track.add(nums[i]);}}Collections.reverse(track);return track;}
}

dp数组定义:dp[i][0]代表不偷第i号房屋所能获得最大金额
dp[i][1]代表偷第i号房屋所能获得最大金额
递推公式:不偷第i号房屋所能获得最大金额就是一定得偷第i号房屋也就是dp[i][0] = dp[i - 1][1]
偷第i号房屋所能获得最大金额有两种情况:

  1. 偷i-2号房屋,这个好理解
  2. 不偷i-2号房屋,比如说[2,1,1,2]

两者取最大的,也就是dp[i][1] = Math.max(dp[i - 2][1] + nums[i], dp[i - 2][0] + nums[i])
计算路径:得出dp数组后,因为是要计算偷了那几家,因此路径一定是偷了的那家,也就是dp[i][1],然后倒序遍历,如果偷了第i家的最大金额等于target,那就记录路径

3. “213. 打家劫舍 II”

在这里插入图片描述

这题和上一题类似,这题的要求是房屋是一个环,也就是偷了第一家不能偷最后一家,因此,可以考虑分别对0i-1号房屋和1i号房屋分别求最大金额,最后最大金额就是两者最大值

class Solution {public int rob(int[] nums) {if (nums.length == 1) {return nums[0];}int[] dp1 = new int[nums.length - 1];int[] dp2 = new int[nums.length - 1];count(nums, dp1, 0, nums.length - 1);count(nums, dp2, 1, nums.length);return Math.max(dp1[nums.length - 2], dp2[nums.length - 2]);}private void count(int[] nums,int[] dp, int start, int end) {int k = 0;for (int i = start; i < end; i++) {if (i < start + 1) {dp[k] = nums[i];} else if (i == start + 1) {dp[k] = Math.max(nums[i], nums[i - 1]);} else {dp[k] = Math.max(dp[k - 1], dp[k - 2] + nums[i]);}k++;}}
}

4. “337. 打家劫舍 III”

在这里插入图片描述

记录每个节点偷还是不偷,res[0]代表不偷,res[1]代表偷。
当偷时,不能偷该节点的左儿子和右儿子,也就是res[1] = root.val + left[0] + right[0]
当不偷时,可以偷子节点也可以不偷子节点,取最大值,并且左右儿子都是独立的,也就是res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1])
https://leetcode-cn.com/problems/house-robber-iii/solution/dai-ma-sui-xiang-lu-337-da-jia-jie-she-i-j60v/

class Solution {public int rob(TreeNode root) {int[] res = robAction(root);return Math.max(res[0], res[1]);}private int[] robAction(TreeNode root) {int[] res = new int[2];if (root == null) {return res;}int[] left = robAction(root.left);int[] right = robAction(root.right);res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);res[1] = root.val + left[0] + right[0];return res;}
}

http://chatgpt.dhexx.cn/article/Epr8nsbU.shtml

相关文章

oracle 根据部分字段去重

问题&#xff1a;在oracle中使用group by分组&#xff0c;group by子句中必须包含所有的select中的字段和order by子句中的字段。 在不使用group by子句的情况下&#xff0c;进行分组。&#xff08;根据部分字段分组&#xff09; over()分析函数 原sql SELECTIM. ID mediaGrou…

oracle字段去重查询,oracle怎么去重查询

oracle去重查询的方法是&#xff1a; oracle 数据库多字段去重 方法介绍&#xff1a;distinct 关键字、group by 、row_number ()over(partition by 列 order by 列 desc) 我的需求是&#xff1a;根据某几列去重 查询出去重后的全部信息。最后我选择的是第三种方法。 我的想法&…

oracle 数据去重方法

1. 创建表&#xff1a; -- Create table create table TEST_USER (user_id NUMBER(3),user_name VARCHAR2(20),user_age NUMBER(3) ) tablespace GUAN_TABLESPACEpctfree 10initrans 1maxtrans 255storage(initial 64Knext 1Mminextents 1maxextents unlimited);--测试数据…

oracle 字符串去重

select regexp_replace(1,1,3,5,5, ([^,])(,\1)*(,|$), \1\3) from dual;注意&#xff1a; 但是&#xff0c;这个去重&#xff0c;必须建立在排序的基础上&#xff0c;如果listagg拼接出来的数值像 a, b, a, c 这时候&#xff0c;该正则就会失效。

MYSQL/ORACLE多字段去重-根据某字段去重

通过百度上的答案多数无效 自己搞了个 使用oracle row_number()函数&#xff0c;给每个同名的加一个序号&#xff0c;最后筛选第n个想同的即可 oracle与mysql不同 1.oracel 多字段distinct(字段名去重) group by去重失效 可以用row_number() over(partition) 给同名列加个序号…

Oracle 数据去重

在Oracle数据库中删除重复数据 一&#xff0c;查询及删除重复记录的SQL语句 Person01表&#xff1a; 1. 查询表中多余的重复数据&#xff0c;根据ID字段来判断是否重复 SELECT * FROM PERSON01 WHERE ID IN (SELECT ID FROM PERSON01 GROUP BY ID HAVING COUNT(ID) > 1)…

Oracle根据多列去重

&#xff08;1&#xff09;distinct 关键词 distinct用于返回唯一不同的值&#xff0c;可作用于单列和多列 但必须将其放在开头&#xff0c;否则会提示错误 而若在其后添加多个变量名&#xff0c;则返回的将是这多个变量名不同时重复的列&#xff0c;因而使用distinct筛选某…

oracle 数据库去重查询

oracle数据库中有如下一张表&#xff0c;包含id,loginid,name,researchtime等字段&#xff0c;其中name字段中的数据有重复&#xff0c;查询数据时要重复数据只取一条&#xff0c;利用row_number ()over(partition by 列 order by 列 desc)方法实现 1:select a.,row_number() o…

oracle去重函数

1、distinct &#xff08;1&#xff09;、常用的distinct select distinct column from table; &#xff08;2&#xff09;、统计去重后数量 select count(distinct column) from table;–查去重后数量 &#xff08;3&#xff09;、distinct必须放在开头 select id, distinct n…

oracle 数据库 去重查询

oracle 数据库多字段去重 方法介绍&#xff1a;distinct 关键字、group by 、row_number ()over(partition by 列 order by 列 desc) 我的需求是&#xff1a;根据某几列去重 查询出去重后的全部信息。最后我选择的是第三种方法。 我的想法&#xff1a;我想找出一种更简单的方…

Oracle实现去重的两种方式总结

业务场景 需要查询某数据&#xff0c;由于需要三张表关联查询&#xff0c;查询结果如下&#xff1a; 原始SQL语句 SELECT D.ORDER_NUM AS "申请单号" ,D.CREATE_TIME ,D.EMP_NAME AS "申请人",(SELECT extractvalue(t1.row_data,/root/row/FI13_wasteNam…

mysql默认密码的查找与修改

注&#xff1a;此方法仅可用于初始安装数据库或学习时使用&#xff0c;在实际生产中会使所有数据库文件删除&#xff0c;故应先提前备份相关重要数据&#xff0c;以免造成不必要的损失&#xff0c;请谨慎使用。 若使用mysqld –initialize初始化mysql数据库&#xff0c;会产生一…

rpm安装mysql后密码_CentOs安装Mysql和配置初始密码

装载自&#xff1a;https://www.cnblogs.com/FlyingPuPu/p/7783735.html 一、Mysql下载安装 使用上传命令上传至/home目录&#xff0c;如&#xff1a;rz命令(yum install -y lrzsz) 添加mysql仓库(-Uvh后面接的为你下载的rpm文件名) sudo rpm -Uvh mysql57-community-release-e…

MySQL初始密码的查看

问题&#xff1a;在安装MySQL过程中&#xff0c;以管理员身份运行cmd后进入MySQL的bin目录&#xff0c;然后输入命令“mysqld --initialize”后没有显示初始密码&#xff0c;没办法进行后续的登录怎么办&#xff1f; 1.打开你的MySQL的安装目录下的data文件夹&#xff08;就是…

如何找到mysql的初始密码_如何查看mysql的初始密码

如何查看mysql的初始密码 发布时间:2020-08-26 11:50:11 来源:亿速云 阅读:95 作者:Leah 今天就跟大家聊聊有关如何查看mysql的初始密码,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。 查看mysql的初始密码的…

[mysql]linux服务器mysql默认密码查看

通过 cat /var/log/mysqld.log | grep password 命令查看数据库的密码

centos查看mysql默认密码和修改密码

1、查看mysql默认密码&#xff1a; grep ‘temporary password’ /var/log/mysqld.log rootlocalhost: b_1sZou9FZrt b_1sZou9FZrt就是 2、修改mysql密码&#xff1a; ALTER USER ‘root’‘localhost’ IDENTIFIED BY ‘new password’; ‘new password’替换成你要设置的密…

宝塔中查看mysql默认密码

文章目录 一、查看root密码二、说明三、如何用工具连接数据库 一、查看root密码 二、说明 创建数据库后&#xff0c;请设置一个新的用户&#xff0c;授予操作该库所需的权限&#xff0c;并使用该用户进行数据库操作&#xff0c;不要将root 账户密码设置为 root 123456 admin 等…

mysql初始密码在哪个文件_mysql-5.7.26-安装教程

首先下载mysql-5.7.26-winx64安装文件&#xff0c;链接地址https://www.mysql.com/downloads/ 然后MySql解压地址为D:Program Filesmysql-5.7.26-winx64下 然后加入环境变量 点击系统变量下的新建按钮 输入变量名&#xff1a;MYSQL_HOME 输入变量值&#xff1a;D:Program Files…

Mac下MySql初始密码设置及mysql数据库操作

转载 &#xff1a; https://www.cnblogs.com/tugenhua0707/p/10725952.html 1. 首先 点击系统偏好设置 -> 点击MySQL, 在弹出的页面中&#xff0c;关闭服务。 2. 进入终端命令输出: cd /usr/local/mysql/bin/ 命令&#xff0c;回车。 3. 回车后&#xff0c;输入命令&…