House Robber II:打家劫舍 取非相邻元素求和最大,且认为第一个元素与最后一个元素相邻

Note: This is an extension of House Robber.

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 are arranged 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.


打家劫舍 取非相邻元素求和最大,且认为第一个元素与最后一个元素相邻

举例:1 1 1 输出1

1 2 3 1 输出4

0 输出0

1 3 输出3

思路:标准的动态规划,和普通的House Robber.类似,因为第一个元素与最后一个元素不能同时取,所以分别对0-(n-2)与1-(n-1)各位元素取符合题意的最值,再取最大者。

代码写的很啰嗦,可以看Leetcode上的简洁版┗|`O′|┛ 嗷~~

class Solution {
    int result = 0;  
    public int get(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]);
        int d[] = new int[nums.length+1];
        d[0] = 0;
        d[1] = nums[0];
        d[2] = Math.max(nums[0],nums[1]);
        for(int i = 3;i<=nums.length;i++){
            d[i] = Math.max(d[i-1],d[i-2]+nums[i-1]);
        }
        return d[nums.length];
    }   
    
    
    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]);
        int[] a1 = new int[nums.length];
        int[] a2 = new int[nums.length];
        for(int i = 0;i<nums.length-1;i++){
            a1[i] = nums[i];
            a2[i] = nums[i+1];
        }
        return Math.max(get(a1),get(a2));    
        
    }
}
简化版本:

private int rob(int[] num, int lo, int hi) {
    int include = 0, exclude = 0;//对于数组中的每一个元素,都包含两种选法:选取当前元素include,不选取当前元素exclude
    for (int j = lo; j <= hi; j++) {
        int i = include, e = exclude;//include表示选取当前元素的选法,exclude表示不选取当前元素的选法
        include = e + num[j];//如果选取当前元素,那么就得选择没有选取前一元素的选法,因为相邻元素不能同时取
        exclude = Math.max(e, i);//对于不选取当前元素的选法,应该是之前一步中总和最大的两种选法
    }
    return Math.max(include, exclude);/选择两种选法中最大的选法
}

public int rob(int[] nums) {//由于第一个元素与最后一个元素不能同时选取,所以把他们分开成两组,在分别计算最优值,取最大者
    if (nums.length == 1) return nums[0];
    return Math.max(rob(nums, 0, nums.length - 2), rob(nums, 1, nums.length - 1));
}



 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值