LeetCode Hot 100 No.198 打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 1:

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

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

思路:
这道题是动态规划问题。
1,2,3,1
例如这四个房子。我们从前往后依次遍历,每当我们到达一个房子的时候,我们都会有两种选择,
第一种就是偷它,但是我就不能偷它左边的房子了。
第二种就是我不偷这个房子,但是我可以偷它左边的房子。
我们用两个数组来保存偷每个房子和不偷每个房子所能得到的总钱数。
int[] steal;
int[] notsteal;
1.对于第一个房子1,steal [0]=1. notsteal [0] = 0.这很好理解,因为它之前没有房子,偷这个房子,能得到的钱数就是1,不偷这个房子能得到的钱数就是0.
2.对于第二个房子2, steal [1] = 2+ notsteal [0] .这也很好理解,因为如果偷了2, 那就不能偷 1. 同样的 notsteal [1] = max( steal [0] + notsteal [0]). 这里需要注意,当我不偷2的时候,我既可以偷1 ,也可以不偷1 ,所以当我不偷2时所能得到的总钱数为偷1 和不偷1 的最大值。
3.对于第三个房子3 ,同理, steal [2] = 3+ notsteal [1], notsteal [2] = max( steal [1] + notsteal [1]).
依次类推。。。
当我们遍历到最后一个房子的时候,我们也可以获得偷它和不偷它的总钱数。那么我们偷这所有的房子所能获得的总钱数就是这两个钱数的最大值。
我们可以写出递推公式:
steal [ i ] = nums [ i ] + notsteal [ i-1 ]
notsteal [ i ] = max ( steal [ i-1] , notsteal [ i-1 ] )

本质上就是从后往前的递归,但是这种递归就可以转化为从前往后的形式,这种形式就叫动态规划
我们进一步优化,每次循环我们只要知道 steal [ i-1] 和 notsteal [ i-1 ] 就行了,所以我们就用两个变量来保存上一次循环的结果就可以,不需要再用两个数组保存。

class Solution {
    public int rob(int[] nums) {
        int Stealme = nums[0];
        int notStealme = 0;
        for(int i=1;i<nums.length;i++)
        {
            int lastStealme = Stealme;
            int lastnotStealme = notStealme;
            Stealme = nums[i]+ lastnotStealme;
            notStealme = Math.max(lastStealme,lastnotStealme);
        }
        return Math.max(Stealme,notStealme);

    }
}
上一篇:softmax回归——原理、one-hot编码、结构和运算、交叉熵损失、PyTorch实现


下一篇:周末小短文:Sql如何处理热点key