House Robber II

After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place arearranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

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.

此题思想是动态规划,声明两个变量,一个保存上一个被偷rob时最大值,另一个保存unrob上一个没有被偷的最大值,此时求下一个屋子是,rob=unrob+a[i];unrob=上一次rob和unrob的最大值(因为不一定是偷和被偷时交叉进行的,中间可能有连续几个不偷)。本题是将房子连成环,所以需要访问两次,一次没有最后一个,从0到len-2;一次没有第一个,从1到length-1,最后求最大,此题需要遍历两遍。

public class Solution {
    public int rob(int[] nums) {
        if(nums.length==1)
        return nums[0];
        
        int rob=0;
        int unrob=0;
        for(int i=0;i<nums.length-1;i++){
            
            int temp=unrob;
            unrob=Math.max(rob,unrob);
            rob=temp+nums[i];
            
        }
        int res1=Math.max(unrob,rob);
        unrob=0;
        rob=0;
        for(int i=1;i<nums.length;i++){
           int temp=unrob;
            unrob=Math.max(rob,unrob);
            rob=temp+nums[i];
            
        }
        int res2=Math.max(unrob,rob);
       return Math.max(res1,res2); 
    }
}

  

还有一种写法,空间是O(n),一个数组表示第i个被偷,一个表示第i个没有被偷。代码如下。(非环)

public class Solution {
    public int rob(int[] num) {
        //   31 23 9 13 49 1 0
        //   0  0 0 0
        if(num==null || num.length==0) return 0;

        int n = num.length;

        int [] b = new int[n]; //include last element;
        int [] d = new int[n]; //exclude last element;

        b[0] = num[0];
        d[0] = 0;

        for(int i=1; i<n; i++) {
            b[i] = d[i-1] + num[i];
            d[i] = Math.max(b[i-1], d[i-1]);
        }

        return Math.max(d[n-1], b[n-1]);
    }
} 

 维护一个数组,nums[i]表示到i时最大的钱数。 

public class Solution {  
    //1 2 3  
    public int rob(int[] nums) {  
        if(nums==null || 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(robsub(nums, 0, nums.length-2), robsub(nums, 1, nums.length-1));  
    }  
      
    private int robsub(int[] nums, int s, int e) {  
        int n = e - s + 1;  
        int[] d =new int[n];  
        d[0] = nums[s];  
        d[1] = Math.max(nums[s], nums[s+1]);  
          
        for(int i=2; i<n; i++) {  
            d[i] = Math.max(d[i-2]+nums[s+i], d[i-1]);  
        }  
        return d[n-1];  
    }  
} 

  

你可能感兴趣的:(r)