0198. House Robber (E)

House Robber (E)

题目

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.

Example 1:

Input: nums = [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
             Total amount you can rob = 1 + 3 = 4.

Example 2:

Input: nums = [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
             Total amount you can rob = 2 + 9 + 1 = 12.

Constraints:

  • 0 <= nums.length <= 100
  • 0 <= nums[i] <= 400

题意

在数组里选取一组数,使它们的和最大,但不能选择两个相邻的数。

思路

直接使用DFS会超时,因此在DFS基础上使用记忆化搜索进行优化。

也可以用动态规划的形式:dp数组dp[i]表示以i下标元素为结尾的子数组能够选取的最大和,那么很容易得到初始条件为 (dp[0]=0), (dp[1] = max(nums[0], nums[1])),递推公式为 (dp[i] = max(dp[i-1], dp[i-2]+nums[i]))


代码实现

Java

DFS+记忆化

class Solution {
    public int rob(int[] nums) {
      	// 特殊情况先排除
        if (nums.length == 0) return 0;
        if (nums.length == 1) return nums[0];
        
        Map<Integer, Integer> record = new HashMap<>();
      	// 如果只有0一个入口,那么1永远访问不到,所以需要两个入口并进行比较
        return Math.max(dfs(nums, 0, record), dfs(nums, 1, record));
    }

    private int dfs(int[] nums, int index, Map<Integer, Integer> record) {
        if (index == nums.length - 1) {
            return nums[index];
        }

        if (record.containsKey(index)) {
            return record.get(index);
        }

        int max = 0;
        for (int i = index + 2; i < nums.length; i++) {
            max = Math.max(max, dfs(nums, i, record));
        }

        record.put(index, nums[index] + max);
        return nums[index] + max;
    }
}

动态规划

public int rob(int[] nums) {
        if (nums.length == 0) return 0;
        if (nums.length == 1) return nums[0];

        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);

        for (int i = 2; i < nums.length; i++) {
            dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
        }

        return dp[nums.length - 1];
    }
原文地址:https://www.cnblogs.com/mapoos/p/13139527.html