leetcode [213]House Robber II

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle.That means the first house is the neighbor of the last one. Meanwhile, 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.

Example 1:

Input: [2,3,2]
Output: 3
Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2),
             because they are adjacent houses.

Example 2:

Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
             Total amount you can rob = 1 + 3 = 4.

题目大意:

求小偷能偷钱数的最大值。

解法:

我先认为是将偶数下标数的和与奇数下标数的和做比较,哪一个大,就是小偷可以偷的钱数的最大值,但是忽略了奇数下标和偶数下标的数也能进行组合。于是改用动态规划的方法进行解决,其中要求不能偷相邻的房子,偷第一个房子不能偷最后一个,于是我将两种分开来考虑,第一种情况是不偷最后一个房子,第二种情况是不偷第一个房子。

java:

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

        return res;
    }
}

优化过后的java代码,只使用了两个变量来记录状态:

class Solution {
    private int robCore(int[] nums,int start,int end){
        int first=nums[start];
        int second=Math.max(first,nums[start+1]);
        int res=second;
        for(int i=start+2;i<=end;i++){
            res=Math.max(first+nums[i],res);
            first=second;
            second=res;
        }
        
        return res;
    }

    public int rob(int[] nums) {
        if(nums.length==0) return 0;
        if(nums.length==1) return nums[0];
        if(nums.length==2) return Math.max(nums[0],nums[1]);

        return Math.max(robCore(nums,0,nums.length-2),robCore(nums,1,nums.length-1));
    }
}

  

猜你喜欢

转载自www.cnblogs.com/xiaobaituyun/p/10783737.html
今日推荐