打劫房屋
来源:互联网 发布:手机windows模拟器 编辑:程序博客网 时间:2024/04/27 11:58
打劫房屋 I II
打劫房屋I
描述
假设你是一个专业的窃贼,准备沿着一条街打劫房屋。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,系统会自动报警。
给定一个非负整数列表,表示每个房子中存放的钱,算一算,如果今晚去打劫,你最多可以得到多少钱,在不触动报警装置的情况下。
样例
给定 [3, 8, 4], 返回 8.
挑战
O(n) 时间复杂度 且 O(1) 存储。
递归+缓存方法
class Solution {public: /** * @param A: An array of non-negative integers. * return: The maximum amount of money you can rob tonight * 思路一:直接写递推方程,dp[n]数组保存打劫前n个房间的总价值 * 思路二:按照求解的基本步骤,先递归,再去雍余,然后计划搜索 */ int *dp; long long search(int n,vector<int> &A) { if(n==0)//如果只有一个元素,返回第一个值 return A[0]; if(dp[n]>=0)//如果已经计算过打劫前n个房屋能获得的最大价值,直接返回(去雍余) return dp[n]; dp[n]= max(search(n-1,A),search(n-2,A)+A[n]);//因为不能打劫相邻的房屋,故前 //n个的最大价值应该是max{打劫前n-1个房屋,打劫前n-2个房屋+第n个房屋的价值) return dp[n]; } long long houseRobber(vector<int> A) { // write your code here if(A.size()<0)//边界条件,直接返回 return 0; dp=new int[A.size()];//保存计算过的中间状态,也是缓存的方法 for(int i=0;i<A.size();++i) dp[i]=INT_MIN;//因为是求解最大值,故初始化为-无穷小 long long result=search(A.size()-1,A);//求解打劫n个房屋获取的最大财富 delete []dp; return result; }};
这种方法求解超时,Time Limit Exceeded 总耗时:1272 ms,82% 数据通过测试.
动态规划方法求解:
Accepted 总耗时: 659 ms
class Solution {public: /** * @param A: An array of non-negative integers. * return: The maximum amount of money you can rob tonight * 法二:动态规划求解 * 递推方程:dp[n]=max{dp[n-1],dp[n-2]+A[n]};//因为不能打劫相邻的房屋 * dp[i]表示打劫qiani个房屋所能获取的最大财富 */ long long houseRobber(vector<int> A) { // write your code here long long dp[A.size()]; //边界条件 if(A.size()<0) return 0; if(A.size()==0) return A[0]; dp[0]=A[0]; dp[1]=max(A[0],A[1]); //顺序求解dp[2...n-1] for(int i=2;i<A.size();++i) { dp[i]=max(dp[i-1],dp[i-2]+A[i]);//递推方程,用题意推出,用动态规划求解的关键 } return dp[A.size()-1];//返回最后的结果 }};
打劫房屋 II
描述
在上次打劫完一条街道之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子围成了一个圈,这就意味着第一间房子和最后一间房子是挨着的。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警。
给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,你最多可以得到多少钱 在不触动报警装置的情况下。
注意事项
这题是House Robber的扩展,只不过是由直线变成了圈
样例
给出nums = [3,6,4], 返回 6,你不能打劫3和4所在的房间,因为它们围成一个圈,是相邻的.
class Solution {public: /** * @param nums: An array of non-negative integers. * return: The maximum amount of money you can rob tonight *思路:与打劫房屋1不同的是,这次最后一个房屋不可能和第一个房屋一起打劫 * 故打劫房屋第0个房间到第n-1个房间问题转换成求解 * max{打劫房屋第0个房间到第n-2个房间,打劫房屋第1间到第n-1间房屋} * 简单的来说:对于第0间和第n-1间的关系就是-->有他没我,有我没他 * 继续使用动态规划求解,递推方程如下: * dp[i]=max{dp[i-1],dp[i-2]+nums[i]} i>=2 */ //serach()函数返回的是从指定下标房间号start位置到下标n位置打劫的最大财富 int search(const vector<int> &nums,int start,int n) { //start代表起始房间下标,n代表可以打劫到最后一个房间的下标 vector<int>dp(n+1,INT_MIN);//保留求解子问题的最优解,注意,开辟空间为n+1 if(n<1)//边界条件,只有一个房间,直接返回 return nums[start]; dp[start]=nums[start];//只有一个房间时 dp[start+1]=max(nums[start],nums[start+1]);//只有两个房间时 for(int i=start+2;i<=n;++i) dp[i]=max(dp[i-1],dp[i-2]+nums[i]); return dp[n];//dp[n]保存的就是打劫从第start下标开始的房间号到第n间得到的总财富 } int houseRobber2(vector<int>& nums) { // write your code here int n=nums.size(); int result1=0;//result1用来保存打劫第0间到第n-2间的最大财富 int result2=0;//result2用来保存打劫第1间到第n-1间的最大财富 //边界条件 if(n<0) return 0; if(n==1)//如果只有一个元素,直接返回此元素的值 return nums[0]; result1=search(nums,0,n-2); result2=search(nums,1,n-1); return result1>result2 ? result1:result2; }};
1 0
- 打劫房屋
- 打劫房屋
- 打劫房屋
- 打劫房屋 II和打劫房屋 III
- LintCode-打劫房屋
- lintcode-打劫房屋
- 题目:打劫房屋
- LintCode-打劫房屋
- Lintcode打劫房屋
- 打劫房屋 II
- 打劫房屋 III
- lintcode ----打劫房屋
- 打劫房屋 II
- lintcode打劫房屋
- 【LintCode】打劫房屋
- lintcode打劫房屋
- LintCode:打劫房屋
- LintCode:打劫房屋 II
- 百度Ueditor设置允许上传的图片格式及大小
- 乱搞hash
- noip2016模拟赛day7
- 探营阿里:备战员工吃住在公司 小二晒出3000床被子
- 为什么mysql字段要设置为not null?
- 打劫房屋
- Range Sum Query系列解题报告
- 短链接 设计
- swift 之WKWebView
- 解决windows下 adb shelll 提示device not found的问题
- 多态
- vector用完后需要释放嘛?
- POJ 3979 分数加减法[学习过程]
- 链式与继承