返回
破解 LeetCode 213:环形打家劫舍的动态规划方案
前端
2024-01-28 14:21:34
引言
作为一名技术娴熟的窃贼,你盯上了沿街的一圈房屋,每间都藏有可观的财宝。然而,这些房屋可不是任你轻松偷窃的,它们相互连接着防盗系统,一旦触发就会警铃大作。面对这样的挑战,你将如何制定周密的计划,最大化你的战利品?
动态规划的妙用
破解环形打家劫舍难题的关键在于动态规划。动态规划是一种强大的算法技术,用于解决可以分解成更小重叠子问题的复杂问题。在本例中,我们可以将问题分解成两个子问题:
-
抢劫首间房屋的最佳收益: 这需要考虑抢劫第一间房屋所能获得的收益,以及跳过第一间房屋继续抢劫后续房屋所能获得的收益。
-
不抢劫首间房屋的最佳收益: 这涉及跳过第一间房屋,从第二间房屋开始抢劫,并计算所能获得的最大收益。
算法流程
根据上述子问题,我们可以设计一个动态规划算法:
-
创建两个数组
dp1
和dp2
,长度为n+1
(n
为房屋总数)。 -
dp1[i]
表示抢劫前i
间房屋(包括第i
间)的最大收益。 -
dp2[i]
表示不抢劫第i
间房屋(从第i+1
间房屋开始抢劫)的最大收益。 -
初始化
dp1[0] = 0
和dp2[0] = 0
,表示抢劫前 0 间房屋或不抢劫第 0 间房屋的收益均为 0。 -
对于
i
从 1 到n
:- 计算
dp1[i] = max(dp2[i-1], dp1[i-2] + nums[i])
- 计算
dp2[i] = max(dp1[i-1], dp2[i-2])
- 计算
-
最终,
max(dp1[n], dp2[n])
即为环形打家劫舍的最大收益。
代码示例(Python)
def rob(nums):
n = len(nums)
if n == 0:
return 0
elif n == 1:
return nums[0]
dp1 = [0] * (n+1)
dp2 = [0] * (n+1)
for i in range(1, n+1):
dp1[i] = max(dp2[i-1], dp1[i-2] + nums[i])
dp2[i] = max(dp1[i-1], dp2[i-2])
return max(dp1[n], dp2[n])
结论
通过运用动态规划的思想,我们可以巧妙地解决环形打家劫舍问题。这种算法能够有效地计算在环形结构中抢劫房屋的最大收益,并提供了一个清晰而高效的解决方案。掌握了动态规划的技巧,你将能自信地应对各种类似的编程挑战,并在 LeetCode 中大放异彩。