代码训练营Day.48 | 198. 打家劫舍、213. 打家劫舍II、337. 打家劫舍III

198. 打家劫舍

1. LeetCode链接

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

2. 题目描述

3. 解法

        可以看作一个01背包问题。背包容量为所有房子中存储的金钱总数。

1. dp数组含义:dp[i][j]表示前i个房子在背包容量为j的情况下可以偷盗的最大金额。

2. 递推公式:dp[i][j]等于不加当前房子金额时的和加当前房子金额时中的最大值。即dp[i][j] = dp[i - 1][j] + bdp[i - 2][j - nums[i]] + nums[i](由于不能在相邻房子中偷盗,所以偷盗当前房子时,应该加到上上一行的数上)

3. dp数组初始化:仅用2 * (sum + 1)容量的数组,用nums[0],nums[1]初始化数组。

4. 遍历顺序:物品从第三个开始到最后,注意!!物品遍历时,dp数组的行数跟着遍历,dp数组的列数从后往前遍历。

5. 举例。

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 1) return nums[0];
        int sum = 0;
        for (int i : nums) sum += i;
        vector<vector<int>> dp(2, vector<int>(sum + 1, 0));
        for (int i = nums[0]; i < sum + 1; i++) dp[0][i] = nums[0];
        for (int i = 0; i < sum + 1; i++) dp[1][i] = (i >= nums[1] ? max(nums[1], dp[0][i]) : dp[0][i]);
        for (int j = 0, i = 2; i < nums.size(); j = (j + 1) % 2, i++) {
            for (int k = sum; k >= 0; k--) {
                dp[j][k] = (k >= nums[i] ? max(dp[j][k - nums[i]] + nums[i], dp[(j + 1) % 2][k]) : dp[(j + 1) % 2][k]);
            }
        }
        return nums.size() % 2 == 0 ? dp[1][sum] : dp[0][sum];
    }
};

更简单的方法:

1. dp数组含义:dp[i]表示包括前i个物品的情况下可盗取的最大金额。

2. 递推公式:dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])

3. dp初始化:只初始化dp[0]和dp[1]。

4. 遍历顺序:依次多考虑一件物品。

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 1) return nums[0];
        vector<int> dp(nums.size(), 0);
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < nums.size(); i++) {
            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[nums.size() - 1];
    }
};

213. 打家劫舍II

1. LeetCode链接

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

2. 题目描述

3. 解法

头尾两个房间不能同时盗取,所以考虑三种基本打家劫舍情况,1. 不包含头尾的基本打家劫舍;2. 包含头但不包含尾的基本打家劫舍;3. 不包含尾仅包含头的打家劫舍。而第一种情况包含在2、3中。

所以只需要计算2、3两种情况。然后取两种情况中的最大值。

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 1) return nums[0];
        if (nums.size() == 2) return max(nums[0], nums[1]);
        vector<int> dp(nums.size(), 0);
        vector<int> dp1(nums.size(), 0);
        dp1[1] = nums[1];
        dp1[2] = max(nums[1], nums[2]);
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 3; i < nums.size(); i++) {
            dp1[i] = max(dp1[i - 1], dp1[i - 2] + nums[i]);
        }
        for (int i = 2; i < nums.size() - 1; i++) {
            dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);
        }
        return max(dp[nums.size() - 2], dp1[nums.size() - 1]);
    }
};

我首先想的是利用一个bool数组记录当前最大是否用到了头元素。在这种情况下,当最终的最大值是同时考虑头尾的情况,如果是简单的减去头尾之中的最小值,所得结果仍然不是最终答案。因为同时考虑头元素和尾元素的最终答案,在减去头尾中的最小元素后,与nums中去掉头元素而成的基本打家劫舍问题的最终答案,是完完全全的两个概念。

337. 打家劫舍III

1. LeetCode链接

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

2. 解法

递归后序遍历二叉树,考虑每个节点偷与不偷的情况。

1. 递归参数和输出:参数包含树的节点。输出为当前节点偷与不偷两种情况下各自的最大值所组成的数组,即dp数组。

2. 终止条件:树节点为空,返回0,0;

3. 单层递归逻辑:计算左右孩子的dp数组,根据左右孩子的dp数组,计算当前节点的dp数组。1)不偷当前节点时,数值为左dp最大值 + 右dp最大值;2)偷当前节点时,数值为当前节点值 + 左不偷 + 右不偷。

class Solution {
public:
    vector<int> robTree(TreeNode* root) {
        if (root == nullptr) return {0, 0};
        vector<int> bp(2, 0);
        vector<int> left = robTree(root->left);
        vector<int> right = robTree(root->right);
        bp[0] = left[1] + right[1] + root->val;
        bp[1] = max(left[0], left[1]) + max(right[0], right[1]);
        return bp;
    }
    int rob(TreeNode* root) {
        vector<int> bp = robTree(root);
        return max(bp[0], bp[1]);
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/358084.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Arrays.asList()方法调用add()或remove()抛出java.lang.UnsupportedOperationException问题

在使用Arrays.asList方法将以,分割的字符串转为list集合时&#xff0c;调用add和remove等方法时会抛出java.lang.UnsupportedOperationException。以下为原因和解决方法。 原因&#xff1a; Arrays.asList()方法返回了一个Arrays类的一个继承了AbstractList的ArrayList内部类…

Python面向对象-类专题

在Python中&#xff0c;if __name__ __main__: 这一句是一个常见的模式&#xff0c;用于判断当前的模块是被直接运行还是被导入到其他模块中。 当Python文件被直接运行时&#xff0c;其内置的__name__变量被设置为__main__。但如果这个文件被其他文件导入&#xff0c;__name__…

面向云服务的GaussDB全密态数据库

前言 全密态数据库&#xff0c;顾名思义与大家所理解的流数据库、图数据库一样&#xff0c;就是专门处理密文数据的数据库系统。数据以加密形态存储在数据库服务器中&#xff0c;数据库支持对密文数据的检索与计算&#xff0c;而与查询任务相关的词法解析、语法解析、执行计划生…

海外云手机为什么吸引用户?

近年来&#xff0c;随着全球化的飞速发展&#xff0c;海外云手机逐渐成为各行各业关注的焦点。那么&#xff0c;究竟是什么让海外云手机如此吸引用户呢&#xff1f;本文将深入探讨海外云手机的三大吸引力&#xff0c;揭示海外云手机的优势所在。 1. 高效的社交媒体运营 海外云…

盒子模型的内容总结

知识引入 1.认识盒子模型 在浏览网站时我们会发现内容都是按照区域划分的。这使得网页很工整、美观。在页面中&#xff0c;每一块区域分别承载不同的内容&#xff0c;使得网页的内容虽然零散&#xff0c;但是在版式排列上依然清晰有条理。如图1 图1 *承载内容的区域称为盒子…

Windows系统安装OpenSSH+VS Code结合内网穿透实现远程开发

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

【Lazy ORM 整合druid 实现mysql监控】

Lazy ORM 整合druid 实现mysql监控 JDK 17 Lazy ORM框架地址 up、up欢迎start、issues 当前项目案例地址 框架版本描述spring-boot3.0.7springboot框架wu-framework-web1.2.2-JDK17-SNAPSHOTweb容器Lazy -ORM1.2.2-JDK17-SNAPSHOTORMmysql-connector-j8.0.33mysql驱动druid-…

【人工智能课程】计算机科学博士作业二

使用TensorFlow1.x版本来实现手势识别任务中&#xff0c;并用图像增强的方式改进&#xff0c;基准训练准确率0.92&#xff0c;测试准确率0.77&#xff0c;改进后&#xff0c;训练准确率0.97&#xff0c;测试准确率0.88。 1 导入包 import math import warnings warnings.filt…

七、内存管理单元(MMU)

前言 在多任务的处理器上&#xff0c;往往运行着许多的用户进程&#xff0c;这些进程之间相互隔离&#xff0c;它们都有自己的虚拟存储空间。要实现这样的虚拟存储空间&#xff0c;需要可以进行地址重分配以及虚拟地址到物理地址的转换。 MMU就是实现这种功能的硬件部件&…

哨兵1号回波数据(L0级)提取与SAR成像(全网首发)

本专栏目录:全球SAR卫星大盘点与回波数据处理专栏目录 本文先展示提取出的回波结果,然后使用RD算法进行成像,展示成像结果,最后附上哨兵1号回波提取的MATLAB代码。 1. 回波提取 回波提取得到二维复矩阵数据,对其求模值后绘图如下(横轴为距离向采样点,纵轴为方位向采样…

如何高效复制加密狗:一篇加密狗复制的常见方法全面指南

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

C++实现通讯录管理系统

目录 1、系统需求 2、创建项目 2.1 创建项目 3、菜单功能 4、退出功能 5、添加联系人 5.1 设计联系人结构体 5.2 设计通讯录结构体 5.3 main函数中创建通讯录 5.4 封装联系人函数 5.5 测试添加联系人功能 6、显示联系人 6.1 封装显示联系人函数 7、删除联系人 7.1…

Spring Security简介

什么是Spring Security Spring Security是 Spring提供的安全认证服务的框架。 使用Spring Security可以帮助我 们来简化认证和授权的过程。 官网&#xff1a;Spring Security 对应的maven坐标&#xff1a; <!--security启动器--> <dependency><groupId>or…

Scala入门01

Spark入门 1.入门 spark采用Scala语言开发 Spark是用来计算的 Scala掌握&#xff1a;特性&#xff0c;基本操作&#xff0c;集合操作&#xff0c;函数&#xff0c;模式匹配&#xff0c;trait&#xff0c;样例类&#xff0c;actor等内容。 2.内容讲解 2.1 Scala简介 在http…

Missing or invalid credentials.(Git push报错解决方案)

前言 本文主要讲解git push后报错Missing or invalid credentials的解决方案。这里针对的是windows的。 编程环境&#xff1a;VsCode 问题原因 问题翻译起来就是 凭据缺失或无效。这里我们解决方案是取消vscode里面默认的控制终端git凭据来解决,具体方案如下. 解决方案 1…

金田金业:中国大妈十年炒黄金后有何启发? 黄金交易要有策略

十多年前的2013年中国大妈炒黄金曾威震华尔街&#xff0c;一度成为投资界佳话。当时经过经历2008年全球金融危机五年后随着美国经济持续改善、美国缩减量化宽松规模&#xff0c;在美元强力反弹压制下&#xff0c;国际现货黄金从1700美元下跌到1300美元左右。正是在这个相对低点…

Shell中正则表达式

1.正则表达式介绍 1、正则表达式---通常用于判断语句中&#xff0c;用来检查某一字符串是否满足某一格式 2、正则表达式是由普通字符与元字符组成 3、普通字符包括大小写字母、数字、标点符号及一些其他符号 4、元字符是指在正则表达式中具有特殊意义的专用字符&#xff0c…

C++------高精度减法

题目描述&#xff1a; 分析&#xff1a; 一、A - B分两种情况&#xff1a; 当A>B ----> A - B&#xff1b;当A<B ----> -(B-A); 二、借位 t 的情况&#xff1a; t > 0 : 说明t不需要借位t < 0 : 说明 需要 t10 去补 AC代码如下&#xff1a; #in…

新建react项目,react-router-dom配置路由,引入antd

提示&#xff1a;reactrouter6.4版本&#xff0c;与reactrouter5.0的版本用法有区别&#xff0c;互不兼容需注意 文章目录 前言一、创建项目二、新建文件并引入react-router-dom、antd三、配置路由跳转四、效果五、遇到的问题六、参考文档总结 前言 需求&#xff1a;新建react项…

uniapp瀑布流实现

1. 图片瀑布流&#xff1a; 不依赖任何插件&#xff0c;复制即可见效&#xff1a; <template><view class"page"><view class"left" ref"left"><image class"image" v-for"(item,i) in leftList" :k…