返回
玩转leetcode:动态规划下击破213号难题
前端
2024-02-05 19:14:06
问题解析:
在这个问题中,我们扮演一名专业的小偷,在一条环形街道上,每间房子内都存放着一定的现金。然而,相邻的房子都有一个连通的防盗系统,所以我们无法同时打劫相邻的房子。我们的目标是找到一个最佳的打劫方案,能够获得最多的收益。
思路解析:
为了解决这个问题,我们可以采用动态规划的方法。我们首先将街道分成两部分:第一部分从第一间房子到倒数第二间房子,第二部分从第二间房子到最后间房子。我们分别在这两部分上使用动态规划来求解最佳的打劫方案。
对于第一部分,我们可以定义一个状态变量dp[i],表示在前i间房子中能够偷窃到的最大收益。我们从第一间房子开始,依次考虑每间房子。对于每一间房子,我们有两个选择:偷窃或不偷窃。如果我们偷窃,那么我们可以获得当前房子的收益,但是无法偷窃相邻的房子。如果不偷窃,那么我们可以继续考虑下一间房子。我们选择收益最大的方案作为dp[i]。
对于第二部分,我们也可以定义一个状态变量dp[i],表示在前i间房子中能够偷窃到的最大收益。我们从第二间房子开始,依次考虑每间房子。对于每一间房子,我们也有两个选择:偷窃或不偷窃。如果我们偷窃,那么我们可以获得当前房子的收益,但是无法偷窃相邻的房子。如果不偷窃,那么我们可以继续考虑下一间房子。我们选择收益最大的方案作为dp[i]。
具体实现:
def rob(nums):
if not nums:
return 0
n = len(nums)
# 如果只有一间房子,直接返回其收益
if n == 1:
return nums[0]
# 定义状态变量dp[i],表示在前i间房子中能够偷窃到的最大收益
dp = [0] * n
# 第一部分:从第一间房子到倒数第二间房子
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(2, n - 1):
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
# 第二部分:从第二间房子到最后间房子
dp[1] = nums[1]
dp[2] = max(nums[1], nums[2])
for i in range(3, n):
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
# 返回最大收益
return max(dp[n - 1], dp[n - 2])
扩展与总结:
动态规划是一种强大的算法,可以解决许多现实生活中的优化问题。在本文中,我们使用动态规划来解决leetcode上的213号问题,即"打家劫舍II"。我们从思路解析到具体实现,逐步带领你击破此题,希望对你有所帮助。
结语:
感谢你阅读这篇文章,希望你对动态规划和leetcode有了更深的了解。如果您有任何问题或建议,请随时与我联系。