104. 二叉树的最大深度
高度,深度
本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。
-
二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
-
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数后者节点数(取决于高度从0开始还是从1开始)
-
而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。
迭代法(使用队列)
- 层次遍历,每遍历一层,depth++
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
depth = 0
q = deque([root])
while q:
l = len(q)
depth += 1
for _ in range(l):
cur = q.popleft()
if cur.left:
q.append(cur.left)
if cur.right:
q.append(cur.right)
return depth
递归法
- 最大深度就是左右子树中较大的深度加上自身的一层
class Solution:
def maxDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if root is None:
return 0
else:
# left -> right -> root (post-order)
left_height = self.maxDepth(root.left)
right_height = self.maxDepth(root.right)
return max(left_height, right_height) + 1
559. N 叉树的最大深度
迭代法
- 逻辑对于使用层次遍历来说没有区别
# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
def maxDepth(self, root: 'Node') -> int:
if not root:
return 0
depth = 0
q = deque([root])
while q:
l = len(q)
depth += 1
for _ in range(l):
cur = q.popleft()
for c in cur.children:
q.append(c)
return depth
递归法
# Time complexity: O(N)
# Space complexity: average O(logN); worst O(N)
class Solution(object):
def maxDepth(self, root):
"""
:type root: Node
:rtype: int
"""
if root is None:
return 0
elif root.children == []:
return 1
else:
height = [self.maxDepth(c) for c in root.children]
return max(height) + 1
# or
class Solution:
def maxDepth(self, root: 'node') -> int:
if not root:
return 0
depth = 0
for c in root.children:
depth = max(depth, self.maxDepth(c))
return depth + 1
111. 二叉树的最小深度
迭代法(层次遍历)
- 找到叶子结点就返回当前depth
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
depth = 0
q = deque([root])
while q:
l = len(q)
depth += 1
for _ in range(l):
cur = q.popleft()
if not cur.left and not cur.right:
return depth
if cur.left:
q.append(cur.left)
if cur.right:
q.append(cur.right)
return depth
递归法
- 注意,当左右子树有一个为空时,另一个的最小深度加1才是当前的最小深度
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
# left-subtree is empty
if not root.left and root.right:
return 1 + self.minDepth(root.right)
# right-subtree is empty
if root.left and not root.right:
return 1 + self.minDepth(root.left)
# have both left and right subtrees
return min(self.minDepth(root.left), self.minDepth(root.right)) + 1
222. 完全二叉树的节点个数
完全二叉树的特点
- 除了最后一层的叶子节点,都是满的
- 完全满的二叉树的节点个数是2^k-1,k是层数
- 所以我们可以利用比较左右子树的height值,来加快计算速度。(只需要数最后一层的节点个数)
迭代法(层次遍历)
- 一层层数节点数
- 没有用到完全二叉树的特性
# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
count = 0
q = deque([root])
while q:
l = len(q)
for _ in range(l):
cur = q.popleft()
count += 1
if cur.left:
q.append(cur.left)
if cur.right:
q.append(cur.right)
return count
递归法
- 利用了完全二叉树的特性进行计算
# Time complexity: O(logN * logN)
# Space complexity: O(logN)
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
left_height = 0
cur = root
while cur:
left_height += 1
cur = cur.left
right_height = 0
cur = root
while cur:
right_height += 1
cur = cur.right
if left_height == right_height:
return (2**right_height - 1)
# current node + left-subtree count + right-subtree count
return 1 + self.countNodes(root.left) + self.countNodes(root.right)