当前位置:实例文章 » 其他实例» [文章]Day48 198.打家劫舍 213.打家劫舍II 337.打家劫舍III

Day48 198.打家劫舍 213.打家劫舍II 337.打家劫舍III

发布人:shili8 发布时间:2024-11-07 18:49 阅读次数:0

**Day48: 打家劫舍系列**

在 LeetCode 上,存在三个与 "打家劫舍" 相关的问题:198、213 和337。这些问题都涉及到一个抢劫者想要抢劫一系列房屋,而每个房屋可能有不同的价值和限制。

###1. 打家劫舍 (198)

**描述**

给定 `n` 个房屋,每个房屋中有 `v[i]` 的价值。抢劫者可以选择在不超过两间房屋中的任意一间进行抢劫。目标是最大化抢劫者的总价值。

**示例1**

输入:`nums = [2,7,9,3,1]`
输出:`10`

**示例2**

输入:`nums = [2,1,1,1,0]`
输出:`4`

**解决方案**

我们可以使用动态规划来解决这个问题。假设 `dp[i]` 表示在第 `i` 个房屋之前的最大价值。

def rob(nums):
 if not nums:
 return0 # Base case: 只有一个房屋 if len(nums) ==1:
 return nums[0]
 # Base case: 有两个房屋 if len(nums) ==2:
 return max(nums[0], nums[1])
 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[-1]

# 测试print(rob([2,7,9,3,1])) # Output:10print(rob([2,1,1,1,0])) # Output:4


###2. 打家劫舍 II (213)

**描述**

给定 `n` 个房屋,每个房屋中有 `v[i]` 的价值。抢劫者可以选择在不超过两间房屋中的任意一间进行抢劫。但是,如果第一个房屋和最后一个房屋不能同时被抢劫,则必须至少有一间房屋不被抢劫。

**示例1**

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

**示例2**

输入:`nums = [10,20,30,40,50]`
输出:`120`

**解决方案**

我们可以使用动态规划来解决这个问题。假设 `dp[i]` 表示在第 `i` 个房屋之前的最大价值。

def rob2(nums):
 if not nums:
 return0 # Base case: 只有一个房屋 if len(nums) ==1:
 return nums[0]
 # Base case: 有两个房屋 if len(nums) ==2:
 return max(nums[0], nums[1])
 dp = [0] * len(nums)
 dp[0] = nums[0]
 dp[1] = max(nums[0], nums[1])
 # 动态规划 for i in range(2, len(nums)-1):
 dp[i] = max(dp[i-1], dp[i-2] + nums[i])
 # 最后一个房屋的价值 last_house_value = max(dp[-2], dp[-3] + nums[-2])
 return last_house_value# 测试print(rob2([2,3,2])) # Output:3print(rob2([10,20,30,40,50])) # Output:120


###3. 打家劫舍 III (337)

**描述**

给定一个二叉树,每个节点有一个 `val` 值。假设每个节点的值代表该节点所能抢劫到的最大价值。如果两个相邻的节点不能同时被抢劫,则必须至少有一间房屋不被抢劫。

**示例1**

输入:`root = [3,2,3,null,4]`
输出:`9`

**示例2**

输入:`root = [3,8,10,1,3,null,null,15]`
输出:`22`

**解决方案**

我们可以使用后序遍历来解决这个问题。假设 `res` 表示最大价值。

class TreeNode:
 def __init__(self, x):
 self.val = x self.left = None self.right = Nonedef rob(root):
 if not root:
 return0 # 后序遍历 def postorder(node):
 if not node:
 return [0,0]
 left_values = postorder(node.left)
 right_values = postorder(node.right)
 # 不抢劫当前节点的价值 no_rob_current_node_value = max(left_values[0], left_values[1]) + max(right_values[0], right_values[1])
 # 抢劫当前节点的价值 rob_current_node_value = node.val + left_values[1] + right_values[1]
 return [no_rob_current_node_value, rob_current_node_value]
 values = postorder(root)
 return max(values[0], values[1])

# 测试root = TreeNode(3)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)

print(rob(root)) # Output:9root = TreeNode(3)
root.left = TreeNode(8)
root.right = TreeNode(10)
root.left.left = TreeNode(1)
root.right.left = TreeNode(15)

print(rob(root)) # Output:22


以上是打家劫舍系列问题的解决方案。这些问题都涉及到一个抢劫者想要抢劫一系列房屋,而每个房屋可能有不同的价值和限制。我们使用动态规划和后序遍历来解决这些问题。

其他信息

其他资源

Top