如何解决打家劫舍问题
写完背包问题了,今天写动态规划的经典问题之一的打家劫舍问题。今天就直接上例子,因为这类问题用动态规划五部曲就可以解决,只是递推公式需要好好理解一下。
打家劫舍
题目:198. 打家劫舍 - 力扣(LeetCode)
dp数组及下标含义
dp[i]表示偷窃[0, i]号房能够偷窃到的最高金额
递推公式
不偷i号房,dp[i] = dp[i - 1]
偷i号房,dp[i] = dp[i -2] + nums[i]
综上,dp[i] = max(dp[i - 1], dp[i -2] + nums[i])
初始化
由递推公式知道dp[0]和dp[1]是需要初始化的,再根据dp数组的含义,得到dp[0] = nums[0],dp[1] = max(nums[0], nums[1])
遍历顺序
根据递推公式,dp[i]由dp[i -1]和dp[i - 2]决定,所以从小到大遍历
int rob(vector<int>& nums) {if(nums.zie() == 0)return 0;if(nums.size() == 1)return nums[0];vector<int> dp(nums.size(), nums[0]);dp[1] = max(nums[0], nums[1]);for(int i = 2; i < nums.size(); i++){dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);}return dp[nums.size() - 1];
}
打家劫舍2
题目:213. 打家劫舍 II - 力扣(LeetCode)
这道题的房子形成了一个环,但是换个思路就可以变成上一道题了。将0至n - 2号房和1至n - 1号房分别按第一题计算,这样就不会出现同时偷0号房和n - 1号房的情况,得到的两个结果返回较大值即可。
int robRange(vector<int> nums, int start, int end){if(start == end)return nums[start];vector<int> dp(nums.size(), nums[start]);dp[start + 1] = max(dp[start], dp[start + 1]);for(int i = start + 2; i <= end; i++){dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);}return dp[end];
}int rob(vector<int>& nums) {if(nums.size() == 0)return 0;if(nums.size() == 1)return nums[0];int result1 = robRange(nums, 0, nums.size() - 2);int result2 = robRange(nums, 1, nums.size() - 1);return max(result1, result2);
}
打家劫舍3
题目:337. 打家劫舍 III - 力扣(LeetCode)
dp数组及下标含义
dp[0]表示不偷该节点能够偷窃的最大价值,dp[1]表示偷该节点能够偷窃的最大价值
递推公式
如果不偷该节点,dp[0] = 左孩子dp数组的最大值 + 右孩子dp数组的最大值
如果偷该节点,dp[1] = root -> val + left[0] + right[0]
初始化
dp数组全初始化为0
遍历顺序
采用后序遍历,因为最后由根节点决定是偷孩子节点还是根节点
vector<int> robTree(TreeNode* root){if(root == NULL)return vector<int>(2, 0);vector<int> left = robTree(root -> left);vector<int> right = robTree(root -> right);vector<int> dp(2, 0);dp[0] = max(left[0], left[1]) + max(right[0], right[1]);dp[1] = root -> val + left[0] + right[0];return dp;
}int rob(TreeNode* root) {vector<int> dp = robTree(root);return max(dp[0], dp[1]);
}
这道题有点难,树加上动态规划,不太容易想到思路。
如何解决打家劫舍问题相关推荐
- leetcode - 213. 打家劫舍 II
解题思路:这道题是"打家劫舍I"的升级版,和"打家劫舍I"的区别在于"打家劫舍II"的第一个房子和最后一个房子是相连的,这就导致不能用&qu ...
- javaEE面试重点
Hibernate工作原理及为什么要用? 原理: 1. 读取并解析配置文件 2. 读取并解析映射信息,创建SessionFactory 3. 打开Sesssion 4. 创建事务Transation ...
- 【LeetCode】LeetCode之打家劫舍Ⅱ——暴力递归+动态规划解决循环问题+DP空间优化
这道题和第 198 题相似,建议读者首先阅读「198. 打家劫舍」
- [JS][dp]题解 | #打家劫舍(一)#
题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...
- LeetCode 打家劫舍问题
LeetCode 打家劫舍问题 一:House Robber1 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间 ...
- leetcode 213. House Robber II | 213. 打家劫舍 II(Java)
题目 https://leetcode.com/problems/house-robber-ii/ 题解 这道题是「198. 打家劫舍」的进阶,和第 198 题的不同之处是,这道题中的房屋是首尾相连的 ...
- LeetCode—213. 打家劫舍 II
213. 打家劫舍 II 题目描述:你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的.同时,相邻的房屋装有相 ...
- python解决LeetCode精选Hot100
1.两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...
- Leetcode-213:打家劫舍 II
问题描述: 思路描述: 典型的动态规划题,之前做过打家劫舍 I,这道题和 I 唯一的不同是房子是首尾相邻的,意思偷了第一家就不能偷最后一家,反之亦然:解决思路和打家劫舍 I也相同,维护两个变量,一个记 ...
最新文章
- JS在浏览器中的执行机制
- oss可用性_对象存储OSS详解
- 点云三角化之后还能贴图嘛_雪糕化了之后重新冷冻还能吃吗?宁波这个实验真相了!...
- JS面试之对象(2)
- 一个x86平台的spi flash驱动移植笔记
- EF更新指定字段...
- echo输出换行_Bash shell教程[5] echo命令
- Soul网关源码阅读(十)自定义简单插件编写
- 关于生活的计算机试题,国家电网考试计算机类试题三
- 【贪心School】机器学习课程笔记
- Android Studio的build.gradle里面的各种版本信息
- Warez出品的精品动画,近25万倍的压缩,大小仅有64K的
- 计算机网络4小时速成:应用层,cs模型,p2p模型,DNS域名系统,文件传输协议FTP,电子邮件SMTP,万维网HTTP,动态主机配置协议DHCP
- Java程序在结构上的特点_下面关于JavaApplication程序结构特点描述中,错误的是()...
- android通讯录项目分析,Android 通讯录展示
- 计算机教师招聘笔试总结
- 【实习日记】实习第N天 从零开始搭建一个tiktok puppet(一)
- 土豆 GhostXP SP3 系统5月纯净版
- 安卓 输入法出现导致布局变形问题解决
- WIFI信号放大增强器(中继器)中继成功后怎么改名字
热门文章
- vue ui 的简单使用
- LeetCode之旅(16)
- 计算机大中型机应用领域,把计算机分为巨型机大中型机按照什么分的
- android生成coredump,详解coredump--全面
- yate学习--yateclass.h--class YATE_API Lockable
- 找出一批正整数中的最大偶数_找出一批正整数中最大的偶数,c语言怎么写?
- nginx不能正常加载 CSS问题的解决方法
- picasa 整理照片_使用AddToPicasa将照片快速保存到您的Picasa网络相册中
- 棒球联盟·棒球1号位
- Hello Qt(五十五)———Json简介