House Robber

来源:互联网 发布:电脑版进库出库软件 编辑:程序博客网 时间:2024/06/10 07:17

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.

Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Also thanks to @ts for adding additional test cases.

思路:其实这题跟偷金子那题很类似:实际上,这题应该是2维空间的dp,而我们可以通过降维变成1维的。下面这种写法更加具有通用性;可以扩展到任何问题。

public class Solution {    public int rob(int[] nums) {        if(nums == null || nums.length == 0) return 0;        int[][] dp = new int[2][nums.length+1];        for(int i=0;i<dp.length; i++){            for(int j=0; j<dp[0].length; j++){                dp[i][j] = -1;            }        }        cal(dp, nums, 0, nums.length);        return dp[0][nums.length];    }        public int cal(int[][] dp, int[] nums, int front, int remaining) {        if(remaining == 0) return 0;        if(dp[front][remaining]!=-1) return dp[front][remaining];                int left = -1;        if(front == 0) {            left = nums[nums.length - remaining] + cal(dp, nums, front+1, remaining-1);        }        int right = cal(dp, nums, 0, remaining-1);        dp[front][remaining] = Math.max(left, right);        return dp[front][remaining];    }}
思路2:dp[i]表示的物理意义是:当前从左往右看,最大的可能偷到的value值。注意前面base case的赋值。

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

public class Solution {    public int rob(int[] nums) {        if(nums == null || nums.length == 0) return 0;        if(nums.length == 1) return nums[0];        int[] dp = new int[nums.length];        dp[0] = nums[0];        for(int i=1; i<dp.length; i++){            dp[i] = Math.max(dp[i-1], nums[i] + (i == 1 ? 0 : dp[i-2])); //这种写法是为了House Robber II做准备,这样写可以避免很多corner case;        }        return dp[nums.length-1];    }}

进一步优化空间,因为n的计算只依赖于n-1和n-2,所以只用两个变量就可以了。定义一个size为3的数组,就可以了。

public class Solution {    public int rob(int[] nums) {        if(nums == null || nums.length == 0) return 0;        if(nums.length == 1) return nums[0];        int[] dp = new int[3];        dp[0] = nums[0];        dp[1] = Math.max(nums[0],nums[1]);        for(int i=2; i<nums.length; i++){            dp[2] = Math.max(dp[1], nums[i]+dp[0]);            dp[0] = dp[1];            dp[1] = dp[2];        }        return Math.max(dp[0],Math.max(dp[1],dp[2]));    }}


0 0
原创粉丝点击