House Robber

2018-04-29 20:20:56

The House Robber problem is a classic series of questions on leetcode. Here is an explanation of the topics.

  • 198. House Robber

Problem Description:

Problem solving:

In essence, it is to obtain the maximum value when solving the case of discontinuous fetching. It can be solved using dynamic programming.

dp[i][0]: The i-th number does not take the highest value that can be obtained

dp[i][1]: The i-th number takes the highest value that can be obtained

Initial value: dp[-1][0] = 0, dp[-1][1] = -INF

Recursion: dp[i][0] = max(dp[i - 1][0], dp[i - 1][1])

        dp[i][1] = dp[i - 1] + nums[i]

    public int rob(int[] nums) {
        int[][] dp = new int[nums.length + 1][2];
        dp[0][0] = 0;
        dp[0][1] = Integer.MIN_VALUE;
        for (int i = 1; i <= nums.length; i++) {
            dp[i][0] = Math.max(dp[i - 1][1], dp[i - 1][0]);
            dp[i][1] = dp[i - 1][0] + nums[i - 1];
        }
        return Math.max(dp[nums.length][0], dp[nums.length][1]);
    }

The space complexity can be optimized:

    public int rob(int[] nums) {
        int dp0 = 0;
        int dp1 = Integer.MIN_VALUE;
        for (int i = 1; i <= nums.length; i++) {
            int tmp = dp0;
            dp0 = Math.max(dp1, dp0);
            dp1 = tmp + nums[i - 1];
        }
        return Math.max(dp0, dp1);
    }

 

  • 213. House Robber II

Problem Description:

Problem solving:

Compared with the previous question, there is a loop in this question. Obviously, if the state is a loop, dp cannot be used, because dp only considers the current situation and has no after-effect, and the loop means the following The state affects the previous state, so the first thing we need to do to solve this problem is to consider some means of opening the loop.

For the rob problem, if the ith room is not stolen, then the ith + 1th room can be taken arbitrarily, that is, for the i + 1 room, the ith room is the same as non-existence, so we can Disconnect loops on houses that have not been stolen.

Let's consider the nth room, he has two states, one is stolen, then the n + 1th room must not be stolen, then it is disconnected from n + 1; the second is not stolen, then directly at n disconnect.

    public int rob(int[] nums) {
        if (nums.length == 1) return nums[0];
        return Math.max(helper(nums, 0, nums.length - 2), helper(nums, 1, nums.length - 1));
    }

    private int helper(int[] nums, int l, int r) {
        int dp0 = 0;
        int dp1 = Integer.MIN_VALUE;
        for (int i = l; i <= r; i++) {
            int tmp = dp0;
            dp0 = Math.max(dp0, dp1);
            dp1 = tmp + nums[i];
        }
        return Math.max(dp0, dp1);
    }

 

  • 337. House Robber III

Problem Description:

Problem solving:

This question expands the original problem from the perspective of data structure, and changes the scene to a binary tree. The restriction is still that it cannot be stolen continuously.

In essence, each node still has two states, one is stolen, and the other is not stolen. Therefore, we can still use dynamic programming to connect the left and right sons of each node from low to high. After the state of the point is obtained, calculate its own value.

    public int rob(TreeNode root) {
        int[] res = helper(root);
        return Math.max(res[0], res[1]);
    }

    private int[] helper(TreeNode root) {
        if (root == null) return new int[2];

        int[] res = new int[2];
        int[] L = helper(root.left);
        int[] R = helper(root.right);

        res[0] = Math.max(L[0], L[1]) + Math.max(R[0], R[1]);
        res[1] = L[0] + R[0] + root.val;
        return res;
    }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325097765&siteId=291194637