打家劫舍

972 阅读1分钟

题目描述

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
输出示例

输入:[1, 2, 3, 1]
输出:4
解释:偷窃1号房屋(金额=1),然后偷窃3号房屋(金额=3).
偷窃得到的最高金额为4

输入:[2, 7, 9, 3, 1]
输出:12
解释:偷窃1号房屋(金额=2),然后偷窃3号房屋(金额=9),接着偷窃5号房屋(金额=1).偷窃得到的最高金额为12

解题思路分析

这道题我们需要使用动态规划的思想来解决

  • 由于不可以在相邻的房屋盗窃,所以在当前位置n房屋可盗窃的最大值,要么就是n-1房屋可盗窃的最大值,或者是n-2房屋的值加上当前房屋的最大值,二者之间取最大值
  • 状态转移方程就很好写了:d[n] = max(d[n - 1], d[n - 2] + num[n])
  • 写出了状态转移方程就好写代码了

代码实现

public int rob(int[] nums) {
    if (nums == null || nums.length <= 0) {
        return 0;
    }
    int length = nums.length;
    int[] dp = new int[length + 1];
    //打劫到第0家
    dp[0] = 0;
    //打劫到第1家
    dp[1] = nums[0];
    for (int i = 2; i <= length; i++) {
        //重要的状态转移方程
        dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
    }
    return dp[length];
}