LeetCode House Robber I II III

第一题

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.
相邻的不能同时打劫

题目解答

解题思路

动态规划(Dynamic Programming)

状态转移方程:

dp[i] = max(dp[i - 1], dp[i - 2] + num[i - 1])

其中,dp[i]表示打劫到第i间房屋时累计取得的金钱最大值。

时间复杂度O(n),空间复杂度O(n)

代码实现

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];
    }
}
//另外一种优化O(1)空间
for(int i = 0; i < num.size(); ++i) {
    if (i % 2 == 0) {
        a += num[i];
        //取最大
        a = max(a, b);
    } else {
        b += num[i];
        //取最大
        b = max(a, b);
    }
}

第二题

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.

题目解答

解题思路

因为首尾相连了,所以第一家和最后一家只能抢其中的一家,或者都不抢,那我们这里变通一下,如果我们把第一家和最后一家分别去掉,各算一遍能抢的最大值,然后比较两个值取其中较大的一个即为所求。

代码实现

public class Solution {
    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]);
        int len = nums.length;
        int left = 0;
        int right = len-1;
        return Math.max(robSub(nums, left, right-1), robSub(nums, left+1, right));
    }

    public int robSub(int[] nums, int left, int right) {
        int a = 0, b = 0;
        for(int i = left; i <= right; i++) {
            if(i % 2 == 0) {
                a += nums[i];
                a = Math.max(a, b);
            }else {
                b += nums[i];
                b = Math.max(a, b);
            }
        }
        return Math.max(a, b);
    }
}

第三题

LeetCode House Robber I II III_第1张图片

题目解答

解题思路

后序遍历二叉树,每次遍历返回两个值:分别表示偷窃或者不偷窃当前节点可以获得的最大收益。

代码实现

/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */

//从下到上 相当于后序遍历
public class Solution {
    public int rob(TreeNode root) {
        int[] result = postTraver(root);
        return Math.max(result[0], result[1]);
    }

    public int[] postTraver(TreeNode root) {
        if(root == null) 
            return new int[]{0, 0};
        int[] result = new int[2];
        int[] left = postTraver(root.left);
        int[] right = postTraver(root.right);
        //表示偷
        result[0] = left[1] + right[1] + root.val;
        //表示不偷
        result[1] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        return result;
    }
}

你可能感兴趣的:(LeetCode House Robber I II III)