打家劫舍系列
题目1: 198.打家劫舍
// @lc code=start
class Solution {
// dp[i] 为第i家及以前所有家 能偷到的最高金额
func rob(_ nums: [Int]) -> Int {
if nums.count == 1 { return nums[0] }
var dp = Array(repeating: 0, count: nums.count)
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in 2..<nums.count {
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
}
return dp[nums.count - 1]
}
}
// @lc code=end
题目2:213.打家劫舍II
提供一个思路: 环形问题, 可以舍弃 头或者尾 分别处理最后对比取结果即可。
// @lc code=start
class Solution {
func rob(_ nums: [Int]) -> Int {
if nums.count == 0 { return 0 }
if nums.count == 1 { return nums[0] }
// 不取首元素 做一次打家劫舍
// 不取尾元素 做一次打家劫舍
// 取两个大者
func robFunc(_ nums: [Int]) -> Int {
if nums.count == 0 { return 0 }
if nums.count == 1 { return nums[0] }
var dp = Array(repeating: 0, count: nums.count)
dp[0] = nums[0]
dp[1] = max(nums[1], nums[0])
for i in 2..<nums.count {
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
}
return dp[nums.count - 1]
}
var noHead = robFunc(Array(nums[1..<nums.count]))
var noTail = robFunc(Array(nums[0..<(nums.count - 1)]))
return max(noHead, noTail)
}
}
// @lc code=end
题目3:337.打家劫舍 III
熟悉一下树形dp的操作。
// 动态规划
func rob(_ root: TreeNode?) -> Int {
guard let root else { return 0 }
// 元祖: 取当前节点, 不取当前节点
func dfs(_ root: TreeNode?) -> (Int, Int) {
guard let root else { return (0, 0) }
let left = dfs(root.left)
let right = dfs(root.right)
return (root.val + left.1 + right.1, max(left.0, left.1) + max(right.0, right.1))
}
let res = dfs(root)
return max(res.0, res.1)
}
// 暴力递归搜索, 超时
func rob(_ root: TreeNode?) -> Int {
guard let root else { return 0 }
if root.left == nil, root.right == nil {
return root.val
}
var val = root.val
if let left = root.left {
val += rob(left.left) + rob(left.right)
}
if let right = root.right {
val += rob(right.left) + rob(right.right)
}
var val1 = rob(root.left) + rob(root.right)
return max(val, val1)
}
//暴力递归搜索
//记忆化搜索
// 使 TreeNode 遵守 Hashable 协议
extension TreeNode: Hashable {
static public func == (lhs: TreeNode, rhs: TreeNode) -> Bool {
return lhs.val == rhs.val && lhs.left == rhs.left && lhs.right == rhs.right
}
public func hash(into hasher: inout Hasher) {
hasher.combine(val)
hasher.combine(left)
hasher.combine(right)
}
}
var map = [TreeNode: Int]()
func rob(_ root: TreeNode?) -> Int {
guard let root else { return 0 }
if root.left == nil, root.right == nil {
return root.val
}
if let val = map[root] { return val }
var val = root.val
if let left = root.left {
val += rob(left.left) + rob(left.right)
}
if let right = root.right {
val += rob(right.left) + rob(right.right)
}
var val1 = rob(root.left) + rob(root.right)
let res = max(val, val1)
map[root] = res
return max(val, val1)
}