代码随想录算法训练营第五十五天(动态规划篇)| LeetCode 198.,213. 打家劫舍

本文介绍了使用动态规划解决LeetCode中的两个打家劫舍问题,分别是198题(单向房屋)和213题(环形房屋)。文章详细解释了dp数组的定义、递推公式、初始条件以及代码实现。
摘要由CSDN通过智能技术生成

198. 打家劫舍

题目链接:198. 打家劫舍 - 力扣(LeetCode)

思路

1. dp数组定义

dp[i]: 到包括下标为i的房屋位置,所能偷窃的最大金额。

2. 确定递推公式

决定dp[i]的因素时偷不偷第i个房间。如果偷,那么不能考虑第i-1个房间,所以就看下标i-2以内的房屋所能偷的最大金额加上第i个房间的金额;如果不偷,那么可以考虑第i-1个房间,所以dp值就是dp[i-1](注意这里不一定值一定会偷第i-1个房间,只是说明我们考虑的房间可以包含第i-1个房间。) 因此,递推公式为:

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

3. 初始条件

根据递推公式,要设定dp[0]和dp[1]的值,分别为nums[0]和max(nums[0], nums[1]).

4. 遍历顺序

从前往后

5. 举例推导dp数组

代码实现

class Solution(object):
    def rob(self, nums):
        if len(nums) == 1:
            return nums[0]
        dp = [0]*len(nums)
        dp[0] = nums[0]
        dp[1] = max(nums[0], nums[1])
        for i in range(2, len(nums)):
            dp[i] = max(dp[i-1], dp[i-2] + nums[i])

        return dp[len(nums) - 1]

213. 打家劫舍 Ⅱ

题目链接:213. 打家劫舍 II - 力扣(LeetCode)

思路

房屋是环形,意味着不能同时去第一家和最后一家,所以就分两种情况,一种是不考虑最后一家,一种是不考虑第一家,分别按照上一题的思路求出dp数组,然后去这两种情况中dp[-1]最大的钱财数。

代码实现

class Solution(object):
    def rob(self, nums):
        if len(nums)== 1:
            return nums[0]
        if len(nums) == 2:
            return max(nums[0], nums[1])

        dp1 = [0] * (len(nums) - 1)
        dp2 = [0] * (len(nums) - 1)
        dp1[0] = nums[0]
        dp1[1] = max(nums[0], nums[1])

        for i in range(2, len(nums) - 1):
            dp1[i] = max(dp1[i-1], dp1[i-2] + nums[i])
        dp2[0] = nums[1]
        dp2[1] = max(nums[1], nums[2])

        for i in range(2, len(nums)-1):
            dp2[i] = max(dp2[i-1], dp2[i-2] + nums[i+1])

        return max(dp1[-1], dp2[-1])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值