python - DFS 复杂性,对二叉树中的每个子节点进行两次递归调用
问题描述
因此,假设问题是计算二叉树中总和等于某个目标的路径数。
一种简单的方法是为每个子节点递归调用 DFS 两次,一次用于将子节点用于在其之前某处开始的路径,一次用于开始搜索从子节点开始的路径。
这种方法的时间复杂度为 O(4^k),其中k是树的高度,但是相对于树中的节点数n的复杂度是多少?
我知道常规 DFS 具有 O(n) 时间复杂度,因为它只访问每个树节点一次,但如果我没记错的话,这种方法会访问m 2^m 级的节点。
这是我在python中解决问题的代码。
def cnt_paths(root, target):
return dfs(root, target, 0, set())
def dfs(node, target, current_sum, visited):
cnt = 0
if current_sum + node.val == target:
cnt += 1
if node.left:
cnt += dfs(node.left, target, current_sum + node.val, visited) # include this node
if node.left not in visited:
cnt += dfs(node.left, target, 0, visited) # start from scratch on next node
visited.add(node.left)
if node.right:
cnt += dfs(node.right, target, current_sum + node.val, visited)
if node.right not in visited:
cnt += dfs(node.right, target, 0, visited)
visited.add(node.right)
return cnt
解决方案
您列出的复杂性不正确。如果节点的深度为d,则该节点与和的d个不同起点(根、根的子节点、...节点的父节点或节点本身)一起使用。换句话说,表达式针对特定(但具有不同的值)current_sum + node.val
被评估d次。node
current_sum
这意味着您总共拥有此类操作的 SUM[depth(node)]。在完美的二叉树中,这个和是:
1 + 2*2 + 3*4 + 4*8 + ... + 2 -1
树的高度在哪里。这个总和小于
∑<sub> =1.. 2 -1
等于(2-1),即
O(2)
完美二叉树的节点数=2,所以操作数,改写为:
O(log())
推荐阅读
- php - 无法使用 Xdebug 检查 PhpStorm 中的断点
- javascript - 打字稿:在同一级别重用 for .. of 和 for .. in
- arrays - Kotlin - 对象数组(不为空)
- python - 在 matplotlib 中更改 datetime.time 轴的格式
- git - 如何使用 nodegit 检测 git 存储库分歧
- c# - 为什么我不能将具体类添加到具体类实现的接口列表中?
- javascript - css过渡高度隐藏容器中的内容
- python - Python3.7:线程和创建目录
- ruby-on-rails - 从另一个自定义验证中调用验证
- math - 计算非重复排列中元素的索引