• Leetcode刷题详解——打家劫舍 II


    1. 题目链接:213. 打家劫舍 II

    2. 题目描述:

    你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

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

    示例 1:

    输入:nums = [2,3,2]
    输出:3
    解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
    
    • 1
    • 2
    • 3

    示例 2:

    输入:nums = [1,2,3,1]
    输出:4
    解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
         偷窃到的最高金额 = 1 + 3 = 4 。
    
    • 1
    • 2
    • 3
    • 4

    示例 3:

    输入:nums = [1,2,3]
    输出:3
    
    • 1
    • 2

    提示:

    • 1 <= nums.length <= 100
    • 0 <= nums[i] <= 1000

    3. 解法(动态规划):

    3.1 算法思路:

    这个问题是一个环形问题,但是我们可以将环形问题转化为两个单排的问题:

    偷第一个房屋时的最大金额x,此时不能偷最后一个房子,因此就是偷[0,n-2]区间

    不偷第一个房屋时的最大金额y,此时可以偷最后一个房子,因此就是偷[1,n-1]区间的房子

    两种情况的最大值,就是最终的结果

    请添加图片描述

    3.2 C++算法代码:

    class Solution {
    public:
        int rob(vector& nums) {
            // 获取数组长度
            int n = nums.size();
            // 返回两种情况的最大值:偷第一个房子和不偷第一个房子
            return max(nums[0] + rob1(nums, 2, n - 2), rob1(nums, 1, n - 1));
        }
    
        // 定义一个辅助函数,用于计算从left到right范围内能偷到的最大金额
        int rob1(vector& nums, int left, int right) {
            // 如果left大于right,说明没有房屋可以偷,返回0
            if (left > right) return 0;
            // 获取数组长度
            int n = nums.size();
            // 初始化动态规划数组f和g
            vector f(n);
            auto g = f;
            // 将第一个房屋的金额赋值给f[left]
            f[left] = nums[left];
            // 从left+1开始遍历到right,更新动态规划数组f和g的值
            for (int i = left + 1; i <= right; i++) {
                f[i] = g[i - 1] + nums[i]; // 当前房屋的最大金额等于前一个房屋的最大金额加上当前房屋的金额
                g[i] = max(f[i - 1], g[i - 1]); // 当前房屋的最大金额等于前一个房屋的最大金额和前前个房屋的最大金额中的较大值
            }
            // 返回right位置的最大金额,即偷到的最大金额
            return max(f[right], g[right]);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    Android的设计模式-装饰者模式
    初识计算机网络
    2022年贵州省职业院校技能大赛中职组网络安全赛项规程
    element ui 下拉框 选择月份和天数
    糖友可以喝酸奶吗?
    【OpenCV实现平滑图像处理】
    大学生抗疫逆行者网页作业 感动人物HTML网页代码成品 最美逆行者dreamweaver网页模板 致敬疫情感动人物网页设计制作
    11月22日星期三今日早报简报微语报早读
    数据库-MySQL-基础(5)- DQL
    如何从零开始解读产品经理需求分析-需求挖掘
  • 原文地址:https://blog.csdn.net/weixin_51799303/article/details/134515750