golang力扣leetcode 337.打家劫舍III

简介: golang力扣leetcode 337.打家劫舍III

337.打家劫舍III

337.打家劫舍III

题解

题目:给一个二叉树,相邻两个节点不能同时选,问能选的节点累加最大的值

思路:

暴力递归 - 最优子结构

1.既然相邻不能选,那么
method1:选当前节点以及4个孙子节点
method2:不选当前节点,选两个孩子节点
返回max(method1, method2)

记忆化 - 解决重复子问题

爷爷节点会计算孙子节点
父节点也会计算孙子节点
存在重复子问题,用记忆化解决

动态规划

即使用了记忆化剪枝,还是会超时,所以只能用动态规划了
选择当前节点:当前节点的值+不选左孩子节点+不选右孩子节点
selected[root] = root.Val + notSelected[root.Left] + notSelected[root.Right]
不选当前节点 = max(选左孩子,不选左孩子)+max(选右孩子,不选右孩子)
notSelected[root] = max(selected[root.Left], notSelected[root.Left]) + max(selected[root.Right], notSelected[root.Right])

优化

我们发现递归回去的时候,无论是selected[root]还是notSelected[root]
他们的状态始终与notSelected[root.Left] ,notSelected[root.Right],selected[root.Left],selected[root.Right]
这4个有关
所以我们可以定义一个长为2的数组,arr[0]代表选,arr[1]代表不选
在每次递归的时候返回给上一级,节省空间复杂度

代码

TLE 暴力递归 - 最优子结构

func rob(root *TreeNode) int {
  if root == nil {
    return 0
  }
  method1 := root.Val
  if root.Left != nil {
    method1 += rob(root.Left.Left) + rob(root.Left.Right)
  }
  if root.Right != nil {
    method1 += rob(root.Right.Left) + rob(root.Right.Right)
  }
  method2 := rob(root.Left) + rob(root.Right)
  return max(method1, method2)
}
func max(i, j int) int {
  if i > j {
    return i
  }
  return j
}

TLE 记忆化 - 解决重复子问题

func rob(root *TreeNode) int {
  mp := map[*TreeNode]int{}
  var dfs func(root *TreeNode) int
  dfs = func(root *TreeNode) int {
    if _, ok := mp[root]; ok {
      return mp[root]
    }
    if root == nil {
      return 0
    }
    method1 := root.Val
    if root.Left != nil {
      method1 += rob(root.Left.Left) + rob(root.Left.Right)
    }
    if root.Right != nil {
      method1 += rob(root.Right.Left) + rob(root.Right.Right)
    }
    method2 := rob(root.Left) + rob(root.Right)
    mp[root] = max(method1, method2)
    return mp[root]
  }
  return dfs(root)
}
func max(i, j int) int {
  if i > j {
    return i
  }
  return j
}

动态规划

func rob(root *TreeNode) int {
  selected := map[*TreeNode]int{}
  notSelected := map[*TreeNode]int{}
  var dfs func(root *TreeNode)
  dfs = func(root *TreeNode) {
    if root == nil {
      return
    }
    dfs(root.Left)
    dfs(root.Right)
    selected[root] = root.Val + notSelected[root.Left] + notSelected[root.Right]
    notSelected[root] = max(selected[root.Left], notSelected[root.Left]) + max(selected[root.Right], notSelected[root.Right])
  }
  dfs(root)
  return max(selected[root], notSelected[root])
}
func max(i, j int) int {
  if i > j {
    return i
  }
  return j
}

动态规划-优化

func rob(root *TreeNode) int {
  var dfs func(root *TreeNode) [2]int
  dfs = func(root *TreeNode) [2]int { //0选 1不选
    if root == nil {
      return [2]int{0, 0}
    }
    l := dfs(root.Left)
    r := dfs(root.Right)
    selected := root.Val + l[1] + r[1]
    notSelected := max(l[0], l[1]) + max(r[0], r[1])
    return [2]int{selected, notSelected}
  }
  val := dfs(root)
  return max(val[0], val[1])
}
func max(i, j int) int {
  if i > j {
    return i
  }
  return j
}
目录
相关文章
|
1月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
1月前
|
索引
力扣(LeetCode)数据结构练习题(3)------链表
力扣(LeetCode)数据结构练习题(3)------链表
78 0
|
1月前
力扣(LeetCode)数据结构练习题(2)
力扣(LeetCode)数据结构练习题(2)
30 0
|
1月前
|
存储
力扣(LeetCode)数据结构练习题
力扣(LeetCode)数据结构练习题
52 0
|
3月前
|
移动开发 Python
【Leetcode刷题Python】337. 打家劫舍 III
LeetCode 337题 "打家劫舍 III" 的Python解决方案,使用递归和动态规划计算小偷在二叉树结构的房屋中不触发警报的情况下能够盗取的最高金额。
44 1
【Leetcode刷题Python】337. 打家劫舍 III
|
3月前
|
存储 算法 Java
LeetCode经典算法题:打家劫舍java详解
LeetCode经典算法题:打家劫舍java详解
70 2
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
57 6
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
118 2
|
25天前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
20 1