(一)二叉树的深度
递归(分治法):分为求左右两个子树深度的问题,然后合并结果。计算复杂度:o(n),空间复杂度:o(n)
def TreeDepth(self , pRoot: TreeNode) -> int:
# write code here
if not pRoot:
return 0
left=pRoot.left
right=pRoot.right
return max(self.TreeDepth(left), self.TreeDepth(right))+1
DFS遍历:计算复杂度:o(n),空间复杂度:o(n)
def TreeDepth(self , pRoot: TreeNode) -> int:
# write code here
if not pRoot:
return 0
queue, res = [pRoot], 0
while queue:
for i in range(len(queue)):
tmp=queue.pop(0)
if tmp.left:
queue.append(tmp.left)
if tmp.right:
queue.append(tmp.right)
res += 1
return res
(二)二叉搜索树的第k个节点
由于是二插搜索树,进行中序遍历可得到有序数组
def KthNode(self , proot: TreeNode, k: int) -> int:
# write code here
res = []
self.inOrder(proot, res)
if not res or k > len(res) or k <= 0:
return -1
return res[k-1]
def inOrder(self, root, res):
if not root:
return
self.inOrder(root.left, res)
res.append(root.val)
self.inOrder(root.right, res)
(三)重建二叉树
递归的解法:计算复杂度 O(n),空间复杂度 O(n)
def reConstructBinaryTree(self , pre: List[int], vin: List[int]) -> TreeNode:
# write code here
if not pre:
return
root=TreeNode(pre[0])
idx=vin.index(pre[0])
root.left=self.reConstructBinaryTree(pre[1:1+idx],vin[:idx])
root.right=self.reConstructBinaryTree(pre[1+idx::],vin[idx+1::])
return root
(四)树的子结构
递归的解法:计算复杂度o(MN),空间复杂度o(M)
def HasSubtree(self , pRoot1: TreeNode, pRoot2: TreeNode) -> bool:
# write code here
if not pRoot1 or not pRoot2:
return False
return self.isSub(pRoot1,pRoot2) or self.HasSubtree(pRoot1.left,pRoot2) or
self.HasSubtree(pRoot1.right,pRoot2)
def isSub(self,root1,root2):
if not root2:
return True
if not root1:
return False
return root1.val == root2.val and self.isSub(root1.left,root2.left) and
self.isSub(root1.right,root2.right)
(五)二叉树中和为某一值的路径
递归式的深度优先搜索解法
# 返回二维列表,内部每个列表表示找到的路径
def FindPath(self, root, expectNumber):
# write code here
results = []
if root == None:
return results
self.sum = expectNumber
self.DFS(root, results, [root.val])
return results
def DFS(self, root, results,path):
if root.left == None and root.right == None and sum(path) == self.sum:
results.append(path)
if root.left != None:
self.DFS(root.left, results,path+[root.left.val])
if root.right !=None:
self.DFS(root.right, results, path+[root.right.val])
直接遍历二叉树,满足题述条件则将以列表形式存储的路径值保存下来
# 返回二维列表,内部每个列表表示找到的路径
def FindPath(self, root, expectNumber):
# write code here
results = []
if not root:
return results
queue=[root]
paths=[[root.val]]
while queue:
for i in range(len(queue)):
tmp=queue.pop(0)
v=paths.pop(0)
if tmp.left:
queue.append(tmp.left)
paths.append(v+[tmp.left.val])
if tmp.right:
queue.append(tmp.right)
paths.append(v+[tmp.right.val])
if not tmp.left and not tmp.right and sum(v)==expectNumber:
results.append(v)
return results
(六)在二叉树中找到两个节点的最近公共祖先
巧妙的递归解法,满足时间复杂度的要求。较难
def lowestCommonAncestor(self , root: TreeNode, o1: int, o2: int) -> int:
# write code here
def dfs(root, o1, o2):
if not root:
return None
# 如果不是同一层的,那么在根上第一个出现的就是公共祖先
if root.val == o1 or root.val == o2:
return root
left = dfs(root.left, o1, o2)
right = dfs(root.right, o1, o2)
# 如果在同一层出现的,那么必然left和right都有,那么就返回root(该层的根)就行了
if not left:
return right
if not right:
return left
return root
return dfs(root, o1, o2).val
同一类型的题:在二叉搜索树中找最近的公共祖先。判断条件,祖先的结点大小一定在两者之间。