202111-5更文-leetcode198:打家劫舍

216 阅读2分钟

这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

leetcode198:打家劫舍

前文

本文为菜鸟的刷题记录,仅用作笔记使用,并非最佳解决方案。

题目信息

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

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

解题思路分析

解法1

想要知道最多偷取的金额,首先需要对偷窃规则进行分析。小偷不可以对相邻房屋进行偷窃。据此可以分析出,偷窃到当前房屋的最大金额,为三者之中取最大值:偷窃到前一间房屋、偷窃到前两间房屋并偷窃当前房屋、偷窃到前三间房屋并偷窃当前房屋。利用动态规划思想,获取最大偷窃金额的状态转移方程即为三者取最大。同时,直接将偷窃到某间房屋的金额作为dp数组。出于逻辑及空间优化角度考虑,只需要将相邻的两间房屋偷窃金额进行记录即可,对变量进行反复利用,即可对空间复杂度进行优化。n1表示前一间房屋,n2表示前两间房屋,n3表示前三间房屋,对于最开始的三间房屋进行特殊处理。至此,题目分析解决完毕。

public int rob(int[] nums) {
    if(nums.length == 0){
        return 0;
    }else if(nums.length == 1){
        return nums[0];
    }else if(nums.length == 2){
        return Math.max(nums[0],nums[1]);
    }else if(nums.length == 3){
        return Math.max(nums[0] + nums[2],nums[1]);
    }
    int n1 = Math.max(nums[2] + nums[0],nums[1]);
    int n2 = nums[1];
    int n3 = nums[0];
    for (int i = 3; i < nums.length; i++) {
        int max = Math.max(Math.max(n2+nums[i],n3+nums[i]),n1);
        n3 = n2;
        n2 = n1;
        n1 = max;
    }
    return n1;
}

复杂度分析

  • 时间复杂度 o(n)
  • 空间复杂度 o(1)

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。