104. 二叉树的最大深度
难度:☆2
a. 迭代法:层序遍历+队列
队列,二叉树的层序遍历。二叉树的最大深度就是层数,可以直接想到用层序遍历解决。由deque实现一个先进先出的队列,队列里面保存二叉树每一层的节点。通过两层循环遍历,累计层数。
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
queue = deque()
if root:
queue.append(root)
depth = 0
while queue:
size = len(queue)
depth += 1
for _ in range(size):
cur = queue.popleft()
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return depth
b. 递归法:后序遍历
二叉树的深度优先搜索——后序遍历,用递归法实现。
前序遍历求的是深度,后序遍历求的是高度。根节点的高度就是二叉树的最大深度,所以通过后序遍历求根节点的高度,得到二叉树的最大深度。如果知道了左子树和右子树的最大深度 l
和 r
,那么该二叉树的最大深度即为 max(l, r) + 1
。
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
leftDepth = self.maxDepth(root.left) # 左
rightDepth = self.maxDepth(root.right) # 右
depth = 1 + max(leftDepth, rightDepth) # 中(后序遍历)
return depth
精简版:
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
else: # 后序遍历
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
559. N 叉树的最大深度
难度:☆2
a. 迭代法:层序遍历+队列
队列,N 叉树的层序遍历。N 叉树的最大深度就是层数,可以直接想到用层序遍历解决。由deque实现一个先进先出的队列,队列里面保存 N 叉树每一层的节点。通过两层循环遍历,累计层数。
class Solution:
def maxDepth(self, root: 'Node') -> int:
queue = deque()
if root:
queue.append(root)
depth = 0
while queue:
size = len(queue)
depth += 1
for _ in range(size):
cur = queue.popleft()
if cur.children:
queue.extend(cur.children)
return depth
b. 递归法:后序遍历
深度优先搜索——后序遍历,用递归法实现。思路同104题。
class Solution:
def maxDepth(self, root: 'Node') -> int:
if not root:
return 0
depth = 0
for i in range(len(root.children)):
depth = max(depth, self.maxDepth(root.children[i]))
return 1 + depth
111. 二叉树的最小深度
难度:☆2
a. 迭代法:层序遍历+队列
队列,二叉树的层序遍历。deque实现一个先进先出的队列,队列里面保存二叉树每一层的节点。通过两层循环遍历,累计层数,检查若某个节点既没有左孩子,有没有右孩子,则return当前层数。
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
min_depth = 0
if root is None:
return min_depth
queue = deque([root])
while queue:
size = len(queue)
min_depth += 1
for _ in range(size):
cur = queue.popleft()
if not cur.left and not cur.right:
return min_depth
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
b. 递归法:后序遍历
二叉树的深度优先搜索——后序遍历,用递归法实现。
前序遍历求的是深度,后序遍历求的是高度。使用后序遍历,求根节点到叶子节点的最小距离,就是求高度的过程,不过这个最小距离也同样是最小深度。注意根节点只有一个子树的情况,最小深度不是1。
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
leftDepth = self.minDepth(root.left)
rightDepth = self.minDepth(root.right)
if root.left and not root.right:
return 1 + leftDepth
elif root.right and not root.left:
return 1 + rightDepth
else:
return 1 + min(leftDepth, rightDepth)
对比104题,求二叉树的最小深度和最大深度的差别,主要在于处理左右孩子不为空的逻辑。
222. 完全二叉树的节点个数
难度:☆2
a. 迭代法:层序遍历+队列
队列,二叉树的层序遍历。deque实现一个先进先出的队列,队列里面保存二叉树每一层的节点。通过两层循环遍历,累计节点个数,再检查若某个节点有左孩子,则将左孩子入队;若有右孩子,则将右孩子入队。
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
queue = deque([root])
count = 0
while queue:
size = len(queue)
for _ in range(size):
cur = queue.popleft()
count += 1
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return count
b. 递归法:后序遍历(二叉树通用)
二叉树的深度优先搜索——后序遍历,用递归法实现。此处的节点计数方法适用于所有类型的二叉树,不一定是完全二叉树。
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
countLeft = self.countNodes(root.left)
countRight = self.countNodes(root.right)
return countLeft + countRight + 1
极简版:
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
return 1 + self.countNodes(root.left) + self.countNodes(root.right)
c. 递归法:后序遍历(完全二叉树专用)
针对完全二叉树,此法不需要遍历全部节点,即可得知节点个数。思路是:寻找完全二叉树的子树当中的所有满二叉树。根据满二叉树的节点个数和高度 k 的关系:节点个数 = 2k - 1,将子树的节点个数通过后序遍历,向上返回给父节点完成计数。
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
leftP, rightP = root.left, root.right
leftDepth = rightDepth = 0
while leftP:
leftP = leftP.left
leftDepth += 1
while rightP:
rightP = rightP.right
rightDepth += 1
if leftDepth == rightDepth:
return (2 << leftDepth) - 1
return 1 + self.countNodes(root.left) + self.countNodes(root.right)