110 平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
这个题用递归的思路去解决,我们思考,他需要计算每个节点的左右两个子树的高度差
说的是高度,可以用后序遍历求高度
还是递归三部曲
1. 递归参数和返回值:递归参数就是节点,返回值就是高度
2. 递归中止条件:空节点,返回0。如果发现高度大于1 返回-1
3. 单层递归
得到左子树的高度
判断是否为-1
得到右子树的高度
判断是否为-1
确定最终高度 取最大高度。这里是核心,我们还是要返回一个高度
def isBalance(root):
if not root:
return True
def dfs(root):
if not root:
return 0
leftDepth = dfs(root.left)
if leftDepth == -1:
return -1
rightDepth = dfs(root.right)
if rightDepth == -1:
return -1
if abs(leftDepth-rightDepth) > 1:
return -1
else:
depth = 1 + max(leftDepth, rightDepth)
return depth
return False if dfs(root) == -1 else True
257 二叉树所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
又是二叉树,这个题先考虑二叉树的遍历方式。其实从题意就能看到,从根节点开始,
那其实就是前序遍历 中左右。但是,你需要回溯,当你访问到叶子节点,记录之后,需要返回到你的父节点。
递归参数和返回值:递归参数有 节点,path 和存储path的结果。没有返回值
递归中止条件:并不是遍历到叶子节点或者 node==None就返回
如果cur != None and cur.left and cur.right 为None 说明是叶子节点,此时就得
操作path 将存储的节点路径添加进入result中,然后return
单层递归:
中左右
刚开始应该先将 当前节点 cur的值添加进path
然后判断中止条件
左子树找 并且回溯
右子树找 并且回溯 回去的操作就是将path中的元素删除掉一个,你可以理解为删除当前节点。
def allPath(root):
if not root:
return []
path = []
result = []
def dfs(root, path, result):
path.append(root.val) # 中
if root and root.left == None and root.right == None:
res = "->".join(map(str, path))
result.append(res)
return
if cur.left: # 左
dfs(cur.left, path, result)
path.pop() # 回溯
if cur.right: # 右
dfs(cur.right, path, result)
path.pop() # 回溯
dfs(root, path, result)
return result
404 左叶子之和
这个题理解左叶子,不是左子树的叶子。
你如何判断是左叶子呢,靠叶子节点是没办法,考虑父节点
假设父节点是parent. 判断是左叶子,那就是 parent.left and parent.left.left == None and parent.left.right==None。
仍然采用递归
递归参数和返回值:递归参数是节点 返回值是求和
递归中止条件:if not node: return 0 if root.left == None and root.right==None return0
即使是叶子节点,也返回0,你不能直接加叶子节点,这时的叶子节点无法判断是左叶子
单层递归:
采用 左右中的遍历顺序
因此你要对节点求和。你不能一来就求和
def sumOfValues(root):
if not root:
return 0
if root.left == None and root.right == None:
return 0
leftValue = sumOfValues(root.left) # 左
if root.left and root.left.left == None and root.left.right == None:
leftValue = root.left.val
rightValue = sumOfValues(root.right) # 右
sum_ = leftValue + rightValue # 中
return sum_
222 完全二叉树的节点个数
这个题其实就是求二叉树的节点个数的变种
你可以用层次遍历,也可以用一般求二叉树的解法(递归 左右中)。
但是这个题的目的肯定是要考察完全二叉树的性质。
求一般二叉树解法
递归参数和返回值: 返回的是整数值,参数就节点
中止条件:if not node: return 0
单层递归:
左右中
def getNodeSum(root):
def dfs(root)
if not root:
return 0
left = getNodeSum(root.left)
right = getNodeSum(root.right)
sum_ = 1 + left + right
return sum_
return dfs(root)
使用完全二叉树的特性,在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。
完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。
对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
这里的关键在于如何判断一个左子树或者右子树是不是满二叉树?
在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树
def getNodeNum(root):
if not root:
return 0
left = root.left
right = root.right
count = 1
while left and right:
count += 1
left = left.left
right = right.right
if left == None and right == None: # 如果同时到底说明是满二叉树,反之则不是
return 2 ** count - 1
# 如果不是满二叉数 正常遍历 左右中
left = getNodeNum(root.left)
right = getNodeNum(root.right)
sum_ = left + right + 1
return sum_