首页 > 其他分享 >力扣 leetcode 213. 打家劫舍 II

力扣 leetcode 213. 打家劫舍 II

时间:2022-12-11 19:35:17浏览次数:35  
标签:II 偷窃 nums int 力扣 start 房屋 leetcode dp

问题描述

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

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

提示:

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

示例

示例 1:

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

示例 2:

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

示例 3:

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

解题思路

这是一个简单的动态规划问题,其中一个复杂的点是所有房屋围成了一圈,不能同时选第一和最后的房子,如何保证这一点呢?如果我们按常规的动态规划思路来解,我们就要记录之前的状态是否选择了第一间房子,这增加了代码的复杂性。

另一个思路是,直接运行两次动态规划,第一次可选房子的范围是[0, n - 2],第二次可选房子的范围是[1, n - 1]。这样就保证了第一和最后一间房子不会同时被选中。

接着就是常规的动态规划问题,状态转移方程为:

dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])

边界条件为:

dp[i] = nums[0], 当nums.size() == 1 时
dp[i] = max(nums[1], nums[2]), 当nums.size() == 2 时

代码如下:

class Solution {
public:

    int robRange(vector<int>& nums, int start, int end){
        if(start == end){
            return nums[start];
        }
        int a = nums[start];
        int b = max(nums[start], nums[start + 1]);
        int maxProfit = b;
        int cnt = 0;
        for(int i = start + 2; i <= end; i++){ // 动态规划
            if(cnt & 1){
                maxProfit = max(b + nums[i], a);
                b = maxProfit;
            }
            else{
                maxProfit = max(a + nums[i], b);
                a = maxProfit;
            }
            cnt ^= 1;
        }
        return maxProfit;
    }

    int rob(vector<int>& nums) {
        const int n = nums.size();
        if(n == 1){ // 边界条件
            return nums[0];
        }
        else if(n == 2){ // 边界条件
            return max(nums[0], nums[1]);
        }
        else{ // 进行两次动态规划,选择其中最大值
            return max(robRange(nums, 0, n - 2), robRange(nums, 1, n - 1));
        }
    }
};

标签:II,偷窃,nums,int,力扣,start,房屋,leetcode,dp
From: https://www.cnblogs.com/greatestchen/p/16974233.html

相关文章

  • 力扣 leetcode 62. 不同路径
    问题描述一个机器人位于一个mxn网格的左上角(起始点在下图中标记为“Start”)。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为......
  • 力扣---5. 最长回文子串
    给你一个字符串s,找到s中最长的回文子串。示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。示例2:输入:s="cbbd"输出:"bb"提示:   1<=s.length<=......
  • 力扣---509. 斐波那契数
    斐波那契数 (通常用 F(n)表示)形成的序列称为斐波那契数列。该数列由 0和1开始,后面的每一项数字都是前面两项数字的和。也就是:F(0)=0,F(1) =1F(n)=F(n-1)+......
  • 力扣---1137. 第 N 个泰波那契数
    泰波那契序列 Tn 定义如下:T0=0,T1=1,T2=1,且在n>=0 的条件下Tn+3=Tn+Tn+1+Tn+2给你整数 n,请返回第n个泰波那契数 Tn的值。示例1:输入:n=4输......
  • 力扣181(MySQL)- 超过经理收入的员工(简单)
    题目:表:Employee 编写一个SQL查询来查找收入比经理高的员工。以 任意顺序 返回结果表。查询结果格式如下所示。示例1: 解题思路:一、【子查询】先通过子查询......
  • 【Java】【LeetCode】字符串操作
    将空格替换成"%20"Stringa=s.replace("","%20");//注意replace不是直接在s上做修改,而是返回了一个字符串StringBuilderStringBuildersb=newStringBuilder("1234a......
  • 动态规划_打家劫舍III
    package数据结构和算法;publicclassd31_动态规划_打家劫舍III{publicstaticvoidmain(String[]args){//TODO自动生成的方法存根......
  • 力扣每日一题2022.12.11---1827. 最少操作使数组递增
    给你一个整数数组 nums (下标从0开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1 。   比方说,如果 nums=[1,2,3] ,你可以选择增加 nums[1] 得到 n......
  • pgpool ii在lightdb下的性能测试
    1、从​​https://www.pgpool.net/​​下载最新版pgpoolii,如4.3.2。2、假设安装了postgresql或lightdb,百度一搜即可3、解压包,执行./configure &&make&&makeinstall4......
  • 力扣---70. 爬楼梯
    假设你正在爬楼梯。需要n 阶你才能到达楼顶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?示例1:输入:n=2输出:2解释:有两种方法可以爬到楼顶。1.1......