数据结构与算法之 leetcode 动态规划打家劫舍 房屋打劫问题

数据结构与算法阿木 发布于 2025-07-12 6 次阅读


动态规划解决LeetCode:动态规划打家劫舍问题

动态规划(Dynamic Programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学等领域中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划的核心思想是将复杂问题分解为若干个相互重叠的子问题,并存储子问题的解,避免重复计算。

在LeetCode上,有一个经典的动态规划问题——打家劫舍。该问题要求我们计算在不触动警报装置的情况下,一个房子到另一个相邻房子之间最多能偷窃多少金额。这是一个典型的动态规划问题,下面我们将详细探讨其解题思路和实现方法。

问题分析

假设有n个房子,每个房子的金额分别为nums[0], nums[1], ..., nums[n-1]。我们需要计算在不触动警报装置的情况下,最多能偷窃多少金额。

状态定义

定义dp[i]为从第i个房子开始,到第n个房子结束,最多能偷窃的金额。

状态转移方程

对于第i个房子,有两种选择:

1. 偷窃第i个房子,那么就不能偷窃第i-1个房子,此时dp[i] = nums[i] + dp[i-2]。

2. 不偷窃第i个房子,那么dp[i] = dp[i-1]。

状态转移方程为:

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

边界条件

1. 当只有1个房子时,dp[0] = nums[0]。

2. 当有2个房子时,dp[1] = max(nums[0], nums[1])。

代码实现

下面是使用动态规划解决打家劫舍问题的Python代码实现:

python

def rob(nums):


n = len(nums)


if n == 0:


return 0


if n == 1:


return nums[0]


if n == 2:


return max(nums[0], nums[1])

dp = [0] n


dp[0] = nums[0]


dp[1] = max(nums[0], nums[1])

for i in range(2, n):


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

return dp[-1]


优化空间复杂度

上述代码的空间复杂度为O(n),我们可以进一步优化空间复杂度。

由于状态转移方程只依赖于前两个状态,我们可以使用两个变量来存储前两个状态,从而将空间复杂度降低到O(1)。

python

def rob(nums):


n = len(nums)


if n == 0:


return 0


if n == 1:


return nums[0]


if n == 2:


return max(nums[0], nums[1])

prev2, prev1 = nums[0], max(nums[0], nums[1])


for i in range(2, n):


curr = max(prev1, nums[i] + prev2)


prev2, prev1 = prev1, curr

return prev1


总结

本文介绍了动态规划解决LeetCode:动态规划打家劫舍问题的解题思路和实现方法。通过分析问题,定义状态,建立状态转移方程,我们得到了一个高效的解决方案。我们还对空间复杂度进行了优化,使代码更加高效。

动态规划是一种强大的算法思想,在解决许多实际问题中都有广泛的应用。通过学习动态规划,我们可以更好地理解和解决实际问题。