1. 程式人生 > >[leetcode-213]House Robber II(java)

[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;
    }
}