[leetcode-213]House Robber II(java)

问题描述:
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.

分析:之前做了一道house robberI的问题,是通过DP算法实现的。那这道题的难点在于它构成一个环,所以导致了不知道起点在哪里。起初,我想能不能把环从某个点拆开,发现做不到,因为每个点的取值都由它之前的一个或两个点决定。
后来想到了干脆每个点都做为起始点试试,时间复杂度为O(N2),空间复杂度为O(N),后来又想能不能用二维 DP解决,发现二维DP并不能有效,因为当换个新的起点时,和上个起点获得的数据并不能产生什么联系,所以干脆使用O(n2)的方法试试,结果AC

代码如下:260ms

public class Solution {
    public int rob(int[] nums) {
        int length=nums.length;
        if(length<=0)
            return 0;

        int[] tmpNums = new int[length];
        int max = 0;

        for(int i = 0;i<length;i++){
            tmpNums[i] = nums[i];
            for(int j = 1;j<length-1;j++){
                int index = (i+j)%length;

                int val = nums[index];
                if(j>1)
                    val+=tmpNums[(index+length-2)%length];

                tmpNums[index] = Math.max(tmpNums[(index-1+length)%length],val);
            }
            int tmpMax = tmpNums[(i+length-2)%length];
            if(tmpMax>max)
                max = tmpMax;
        }
        return max;
    }
}

看了网上的介绍,他们只进行了两次遍历,第一次是从第一个遍历到倒数第二个,第二次是从第二个遍历到倒数第一个。那从第三个遍历和从第一个遍历是等价的吗?我脑容量小,想不明白.

代码如下:288ms

public class Solution {
    public int rob(int[] nums) {
        int length = nums.length;
        int max = 0;

        if(length<=2){
            for(int i = 0;i<length;i++){
                if(nums[i]>max)
                    max = nums[i];
            }
            return max;
        }

        int[] tmpNums = new int[length];
        tmpNums[0] = nums[0];
        for(int i = 1;i<length-1;i++){
            int val = nums[i];
            if(i>1)
                val+=tmpNums[i-2];
            tmpNums[i] = Math.max(val,tmpNums[i-1]);
        }
        if(tmpNums[length-2]>max)
            max = tmpNums[length-2];

        tmpNums[1] = nums[1];
        for(int i = 2;i<length;i++){
            int val = nums[i];
            if(i>2)
                val+=tmpNums[i-2];
            tmpNums[i] = Math.max(val,tmpNums[i-1]);
        }
        if(tmpNums[length-1]>max)
            max = tmpNums[length-1];

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值