LeetCode --- House Robber & House Robber II
来源:互联网 发布:jsp页面读取数据库 编辑:程序博客网 时间:2024/05/05 03:44
House Roober
题目链接
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
题目分析
假设当前我们已经到达第[i]个屋子,如图所示
那是否偷第[i]个房子只和前面两个房子是否已经被偷过有关系。
假设f(i)是,当前偷到第i个房子时,获取的最大值,那么我们可以得到如下的状态转移方程
经典的DP问题,所以,代码如下:
class Solution {public: int rob(vector<int>& nums) { if (nums.size() == 0) return 0; if (nums.size() == 1) return nums[0]; vector<int> dp(nums.size() + 1, 0); dp[1] = nums[0]; for (int i = 1; i < nums.size(); i++) { dp[i + 1] = max(nums[i] + dp[i - 1], dp[i]); } return dp[nums.size()]; }};
House Robber II
题目链接
Note: This is an extension of House Robber.
After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police
题目分析
首先街道已经变换为圆形,即首尾相接,那么是否偷第一个已经关系到最后一个是否偷取的问题。
注意上面加黑的一句话
分析一
让我们分三种情况考虑:
- 拿[1]号房子,那么[2]和[N]号不能再拿,另外[3…N-1]退化为了直线型
- 拿[N]号房子,那么[1]和[N-1]号不能再拿,另外[2…N-2]退化为了直线型
- [1]和[N]号房子都不拿,那么[2…N-1]退化为了直线型
所以按照这种情况考虑,代码如下:
class Solution {public: int rob_line(vector<int>& nums, int start, int end) { if (start >= end) return 0; if (end - start == 1) return nums[start]; vector<int> dp(end - start + 1, 0); int dp_ind = 1; dp[dp_ind] = nums[start]; for (int i = start + 1; i < end; i++) { dp_ind++; dp[dp_ind] = max(nums[i] + dp[dp_ind - 2], dp[dp_ind - 1]); } return dp[dp_ind]; } int rob(vector<int>& nums) { if (nums.size() == 0) return 0; return max(rob_line(nums, 1, nums.size() -1), max(rob_line(nums, 2, nums.size() - 1) + nums[0], rob_line(nums, 1, nums.size() - 2) + nums[nums.size() - 1])); }};
改进
在上面的分析中,我们强制取[1]或[N],其实我们把问题复杂化了,因为这样分析我们把动态性降低了,我们可以从相反的方向考虑,则只需要分二种情况即可,即
- 不取[1]
- 不取[N]
那么剩余的房间,都可以转化为直线型,从而比上面的代码减少一个O(N)的时间
class Solution {public: int rob_line(vector<int>& nums, int start, int end) { if (start >= end) return 0; if (end - start == 1) return nums[start]; vector<int> dp(end - start + 1, 0); int dp_ind = 1; dp[dp_ind] = nums[start]; for (int i = start + 1; i < end; i++) { dp_ind++; dp[dp_ind] = max(nums[i] + dp[dp_ind - 2], dp[dp_ind - 1]); } return dp[dp_ind]; } int rob(vector<int>& nums) { if (nums.size() == 0) return 0; if (nums.size() == 1) return nums[0]; return max(rob_line(nums, 0, nums.size() - 1), rob_line(nums, 1, nums.size())); }};
备注:上述状态转移方程,当前状态只和前两个状态有关,存储空间可以压缩为O(1)的,读者自行实现吧
- 【dp】Leetcode House Robber&& House Robber II
- 【leetcode】House Robber && House Robber II
- LeetCode --- House Robber & House Robber II
- LeetCode House Robber II
- [LeetCode] House Robber II
- [leetcode] House Robber II
- 【leetcode】House Robber II
- Leetcode: House Robber II
- leetcode House Robber II
- [leetcode] House Robber II
- [LeetCode]House Robber II
- leetcode--House Robber II
- leetcode House Robber II
- LeetCode House Robber II
- leetcode:House Robber II
- Leetcode: House Robber II
- House Robber II -- leetcode
- leetCode House Robber II
- Qt头文件包含问题
- Android应用开发:页面跳转和数据传递
- 请务必注意 Redis 安全配置,否则将导致轻松被入侵
- 关于oc 开发上传图片 功能遇到的问题分享
- 使用jQuery的hover事件在IE中不停闪动的解决方法
- LeetCode --- House Robber & House Robber II
- CF 600C 贪心+字符串
- hbase跨版本导数
- [BZOJ1010][HNOI2008]玩具装箱toy 斜率优化第一题
- linux中将文件或者文件夹权限分配给某个用户
- hibernate第三天——session的缓存与事务隔离级别,一对一关系,多种方式查询
- 细节错误
- Java与数据库数据类型对应表
- activity界面架构即activity视图层结构