198. House Robber

题目:

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that 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.

Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Also thanks to @ts for adding additional test cases.

Hide Tags
 Dynamic Programming 

链接:  http://leetcode.com/problems/house-robber/

题解:

一维DP,  当前最大值相当于Math.max(nums[i - 1],nums[i] + nums[i - 2]),处理一下边界情况就可以了。

Time Complexity - O(n), Space Complexity - O(1)。

public class Solution {
    public int rob(int[] nums) {
        if(nums == null || nums.length == 0)
            return 0;
            
        for(int i = 0; i < nums.length; i++){
            int temp1 = i - 1 < 0 ? 0 : nums[i - 1];
            int temp2 = i - 2 < 0 ? 0 : nums[i - 2];
            nums[i] = Math.max(temp1, nums[i] + temp2);
        }
        
        return nums[nums.length - 1];
    }
}

Update:

public class Solution {
    public int rob(int[] nums) {
        if(nums == null || nums.length == 0)
            return 0;
        int prePre = 0, pre = 0;
        
        for(int i = 0; i < nums.length; i++) {
            prePre = i - 2 >= 0 ? nums[i - 2] : 0;
            pre = i - 1 >= 0 ? nums[i - 1] : 0;
            nums[i] = Math.max(nums[i] + prePre, pre);
        }
        
        return nums[nums.length - 1];
    }
}

Update:

做到了House Rob II,返回来思考,以下写会比较方便,不用更改原数组,用三个变量就可以了。跟Climb Stairs很像

public class Solution {
    public int rob(int[] nums) {
        if(nums == null || nums.length == 0)
            return 0;
        int prePre = 0, pre = 0, max = 0;
        
        for(int i = 0; i < nums.length; i++) {
            if(i - 2 < 0)
                prePre = 0;   
            if(i - 1 < 0)
                pre = 0;
            max = Math.max(nums[i] + prePre, pre);
            prePre = pre;
            pre = max;
        }
        
        return max;
    }
}

二刷:

dp依然不过关啊...

Java:

更改原数组的.

public class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            int notRobLastHouse = i - 2 >= 0 ? nums[i - 2]: 0;
            int robLastHouse = i - 1 >= 0 ? nums[i - 1] : 0;
            nums[i] = Math.max(robLastHouse, notRobLastHouse + nums[i]);
        }
        return nums[len - 1];
    }
}

分别记录robLast和notRobLast的

public class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int notRobLastHouse = 0;
        int robLastHouse = 0;
        for (int i = 0; i < nums.length; i++) {
            if (i % 2 == 0) {
                notRobLastHouse = Math.max(notRobLastHouse + nums[i], robLastHouse);
            } else {
                robLastHouse = Math.max(robLastHouse + nums[i], notRobLastHouse);
            }
        }
        return Math.max(notRobLastHouse, robLastHouse);
    }
}

类似Climb Stairs的

public class Solution {
    public int rob(int[] nums) {
        if(nums == null || nums.length == 0) {
            return 0;
        }
        int prePre = 0, pre = 0, max = 0;
        
        for (int i = 0; i < nums.length; i++) {
            max = Math.max(nums[i] + prePre, pre);
            prePre = pre;
            pre = max;
        }
        return max;
    }
}

三刷:

Java:

dp - O(n) Space,  我们先建立一个长为len + 1的dp数组,dp[i]代表到原数组第i - 1位为止,最大的profit,然后设置dp[1] = nums[0],之后就可以用转移方程比较dp[i - 1]和dp[i - 2] + nums[i - 1]来求得dp[i]。最后返回dp[len]

public class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int len = nums.length;
        int[] dp = new int[len + 1];
        dp[1] = nums[0];
        for (int i = 2; i <= len; i++) {
            dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
        }
        return dp[len];
    }
}

dp O(1) Space :  同样我们可以压缩space complexity到O(1),可以使用和climbing stairs类似的方法,用三个变量来保存临时结果。robLast和notRobLast分别代表 i - 1步和i - 2步。

public class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int profit = 0, robLast = 0, notRobLast = 0;
        for (int i = 0; i < nums.length; i++) {
            profit = Math.max(robLast, notRobLast + nums[i]);
            notRobLast = robLast;
            robLast = profit;
        }
        return profit;
    }
}

Update:

public class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) return 0;
        int robLast = 0, notRobLast = 0, res = 0;
        for (int num : nums) {
            res = Math.max(notRobLast + num, robLast);
            notRobLast = robLast;
            robLast = res;
        }
        return res;
    }
}

  

Reference:

https://leetcode.com/discuss/30079/c-1ms-o-1-space-very-simple-solution

https://leetcode.com/discuss/30020/java-o-n-solution-space-o-1

https://leetcode.com/discuss/31878/java-dp-solution-o-n-runtime-and-o-1-space-with-inline-comment

原文地址:https://www.cnblogs.com/yrbbest/p/4491669.html