LeetCode | 198. House Robber, 213. House Robber II, 337. House Robber III

198. House Robber

Link: https://leetcode.com/problems/house-robber/

Description

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 systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.

Approach

  • If there is only one house, return the money of the house.
  • Else, create an array dp of the same length as the nums array to store the maximum amount of money that can be robbed up to that house.
  • Initialize dp[0] with nums[0] and dp[1] with the maximum of nums[0] and nums[1].
  • Iterate through the nums from the third house to the last house:
    • Select the maximum amout of money between robbing the previous house dp[i - 1] and robbing from the current house nums[i] and the two houses back dp[i - 2].

Solution

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

213. House Robber II

Link: https://leetcode.com/problems/house-robber-ii/

Description

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.

Approach

  • If there is only one house, return the money of the house.
  • Split the robber into two situations, one excludes the first house, the other one excludes the last house and return the maximum of the two situations.
  • Initialize a recursive function with parameters nums, start (the start of the array), end (the end of the array).
  • Call the function with the two mentioned situations above and return the maximum value.
  • Inside the recursive function:
    • if there is only one processed house in the range, return the value of the house.
    • Else, create an array dp of the same length as nums to store the maximum amount of money that can be robbed up to each house within the given range.
    • Initialize dp[0] with nums[start] and dp[1] with the maximum of nums[start] and nums[start + 1].
    • Iterate through the nums in the given range starting from the third house:
      • Select the maximum amout of money between robbing the previous house dp[i - 1] and robbing from the current house nums[i] and the two houses back dp[i - 2].
    • Return dp[end].

Solution

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

    private int robAction(int[] nums, int start, int end) {
        if (start == end)
            return nums[start];
        int[] dp = new int[nums.length];
        dp[start] = nums[start];
        dp[start + 1] = Math.max(dp[start], nums[start + 1]);
        for (int i = start + 2; i <= end; i++)
            dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
        
        return dp[end];
    }
}

337. House Robber III

Link: https://leetcode.com/problems/house-robber-iii/

Description

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called root.

Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that all houses in this place form a binary tree. It will automatically contact the police if two directly-linked houses were broken into on the same night.

Given the root of the binary tree, return the maximum amount of money the thief can rob without alerting the police.

Approach

  • Initialize a result array where result[0] represents the maximum amount of money that can be obtained without robbing the current node, and result[1] represents the maximum amount of money that can be obtained with robbing the current node.
  • Initialize a recursive function with parameter root (represents the curent house) and call it with the first house.
  • Inside the recursive function:
    • Initialize a result array where result[0] represents the maximum amount of money that can be obtained without robbing the current node, and result[1] represents the maximum amount of money that can be obtained with robbing the current node.
    • If the node is null, return the result array.
    • Call the function with the left child and right child, obtain respective result arrays.
    • result[0] is the maximum between the maximum amount from the left subtree without and with robbing the left child, and the maximum amount from the right subtree without and with robbing the right child.
    • result[1] is the addtion of the value of current node, maximum amount without robbing the left child and maximum amount without robbing the right child.
    • Return result.

Solution

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int rob(TreeNode root) {
        int[] result = new int[2];
        result = robAction(root);
        return Math.max(result[0], result[1]);
    }

    private int[] robAction(TreeNode root) {
        int[] result = new int[2];
        if (root == null)
            return result;
        int[] left = robAction(root.left);
        int[] right = robAction(root.right);
        
        result[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        result[1] = root.val + left[0] + right[0];
        return result;
    }
}

你可能感兴趣的:(leetcode,算法)