打劫房屋III
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打劫房屋III相关的知识,希望对你有一定的参考价值。
打劫房屋I 题目
假设你是一个专业的窃贼,准备沿着一条街打劫房屋。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警。
给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,你最多可以得到多少钱 在不触动报警装置的情况下。
解题:
(一)定义dp[i]表示打劫第i个房间为止所获得的最大收益,而dp[i]的值只与dp[i-2] 和dp[i-3]有关,并且 dp[i] = A[i] + max(dp[i-2],dp[i-3])
当求解所有的A[i]后,需要对最后两个dp[len-1] dp[len-2] 取最大值作为最后的答案。
public long houseRobber(int[] A) { int len = A.length; if(len==0) return 0; // dp[i] 表达打劫i房间为止所活动的收获 ,与dp[i-2] dp[i-3]有关 long[] dp = new long[len]; dp[0] = A[0]; if(len==1){ return dp[0]; }else if(len==2){ dp[1] = A[1]; return Math.max(dp[0], dp[1]); }else if(len==3){ dp[1] = A[1]; dp[2] = A[2]; return Math.max(dp[1], dp[2]); } dp[1] = A[1]; dp[2] = A[0] + A[2]; for(int i=3; i<len; i++){ dp[i] = A[i] + Math.max(dp[i-2], dp[i-3]); } return Math.max(dp[len-2], dp[len-1]); }
(二)不用数组。O(n) 时间复杂度 且 O(1) 存储
i-3 | i-2 | i-1 | i |
max0 | max1 | max2 | max3 |
对第i处的最大值max3 = A[i] + max(max1,max0)
当是i+1个的时候,更新max0、max1、max2
max0 = max1
max1 = max2
max2 = max3
public long houseRobber(int[] A){ int len = A.length; if(len==0) return 0; if(len==1) return A[0]; if(len==2) return Math.max(A[0], A[1]); if(len==3) return Math.max(A[1], A[0]+A[2]); long max0, max1, max2, max3; max0 = A[0]; max1 = A[1]; max2 = Math.max(max1, A[2]+max0); max3 = 0; for(int i=3; i<len; i++){ max3 = A[i] + Math.max(max0, max1); max0 = max1; max1 = max2; max2 = max3; } return Math.max(max3, max1); }
打劫房屋II 题目
在上次打劫完一条街道之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子围成了一个圈,这就意味着第一间房子和最后一间房子是挨着的。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警。
给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,你最多可以得到多少钱 在不触动报警装置的情况下。
解题:
根据题目,第0个房间和第n-1个房间只能打劫其中一个
打劫范围只能是:0-n-2 或者1-n-1
所以根据打劫房间I的程序,修改为根据范围进行打劫,再求这个两个打劫的最大值。
public int houseRobber2(int[] nums) { // write your code here if(nums==null || nums.length==0) return 0; int len = nums.length; if(len==1) return nums[0]; if(len==2) return Math.max(nums[0], nums[1]); if(len==3) return Math.max(Math.max(nums[1], nums[0]), nums[2]); int res1 = houseRobber(nums, 0, len-2); int res2 = houseRobber(nums, 1, len-1); return Math.max(res1, res2); } // 打劫房屋I(打劫范围) private int houseRobber(int[] nums, int start, int end){ if(start==end) return nums[start]; if(start+1 == end) return Math.max(nums[start], nums[end]); if(start+2 == end) return Math.max(nums[start+1], nums[start]+nums[end]); int len = nums.length; int[] dp = new int[len]; dp[start] = nums[start]; dp[start+1] = nums[start+1]; dp[start+2] = nums[start+2] + dp[start]; for(int i=start+3; i<=end; i++){ dp[i] = nums[i] + Math.max(dp[i-2], dp[i-3]); } return Math.max(dp[end], dp[end-1]); }
以上是关于打劫房屋III的主要内容,如果未能解决你的问题,请参考以下文章