【两次过】Lintcode 534. 打劫房屋 II

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/majichen95/article/details/89041136

在上次打劫完一条街道之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子围成了一个圈,这就意味着第一间房子和最后一间房子是挨着的。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警

给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,在不触动报警装置的情况下, 你最多可以得到多少钱 。

样例

Example1

Input:  nums = [3,6,4]
Output: 6

Example2

Input:  nums = [2,3,2,3]
Output: 6

注意事项

这题是House Robber的扩展,只不过是由直线变成了圈


解题思路:

Lintcode 392. 打劫房屋的升级版。

和第一版类似,不过此时分两种情况,

  1. 打劫第一栋房子,这样最后一栋不打劫
  2. 打劫第二栋房子,这样最后一栋可以打劫

所以使用两个dp数组来分别讨论,最后取两种情况的最大值

public class Solution {
    /**
     * @param nums: An array of non-negative integers.
     * @return: The maximum amount of money you can rob tonight
     */
    public int houseRobber2(int[] nums) {
        // write your code here
        if(nums==null || nums.length<=0)
            return 0;
        
        int n = nums.length;
        //打劫第一间,则不打劫最后一间
        int[] dp1 = new int[n];
        
        dp1[0] = nums[0];
        if(n>1)
            dp1[1] = Math.max(nums[0],nums[1]);
        
        for(int i=2; i<dp1.length; i++){
            if(i == nums.length-1){
                dp1[i] = dp1[i-1];
                continue;
            }
            dp1[i] = Math.max(dp1[i-1], dp1[i-2] + nums[i]);
        }
        
        //不打劫第一间,则能打劫最后一间
        int[] dp2 = new int[n];
        
        dp2[0] = 0;
        if(n>1)
            dp2[1] = Math.max(0,nums[1]);
        
        for(int i=2; i<dp2.length; i++)
            dp2[i] = Math.max(dp2[i-1], dp2[i-2] + nums[i]);
        
        return Math.max(dp1[dp1.length-1], dp2[dp2.length-1]);
    }
}

猜你喜欢

转载自blog.csdn.net/majichen95/article/details/89041136
今日推荐