Leetcode 二叉树 1
题号直达: 94 二叉树的中序遍历 | 104 二叉树的最大深度
LeetCode 94. 二叉树的中序遍历 ↑
题目
给定一个二叉树的根节点 root,返回它的中序遍历。
提示
- 树中节点数目在范围
[0, 100]内 -100 ≤ Node.val ≤ 100
进阶:递归算法很简单,你可以通过迭代算法完成吗?
代码(Python)解法一:递归
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorder(self, root, res):
if not root:
return None
self.inorder(root.left, res)
res.append(root.val)
self.inorder(root.right, res)
def inorderTraversal(self, root):
res = []
self.inorder(root, res)
return res
思路解析(解法一)
- 中序遍历顺序:左子树 → 根结点值 → 右子树,对应递归调用顺序:先
inorder(left),再append(root.val),再inorder(right)。 - 空结点:
root为None时直接返回,不再向下递归。 - 结果列表:由
inorderTraversal创建res,传入辅助函数inorder统一收集,最后返回res。 - 复杂度:每个结点访问一次,时间 O(n),n 为结点数;递归栈深度最坏 O(n)(链状树),平均 O(h),h 为树高。
代码(Python)解法二:迭代(栈)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root):
res = []
stack = []
while root is not None or stack:
while root is not None:
stack.append(root)
root = root.left
root = stack.pop()
res.append(root.val)
root = root.right
return res
思路解析(解法二)
- 核心:用显式栈模拟递归「一路向左」的过程。中序要求先处理完左子树再访问根,因此先把从当前结点沿左孩子一路入栈,直到左子为空。
- 内层
while root:不断stack.append(root)并root = root.left,等价于递归深入左子树。 - 弹出与访问:左走到头后
root = stack.pop(),此时该结点无未处理左子,将root.val记入res,再令root = root.right,转去处理右子树(下一轮可能再次一路向左入栈)。 - 外层条件:
root is not None or stack表示当前还有子树可走或栈里还有待回溯的结点。 - 复杂度:时间 O(n),每个结点入栈、出栈各常数次;空间 O(h),栈深最坏 O(n)(链状树),满足进阶「迭代」写法。
代码(Python)解法三:Morris 中序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root):
res = []
predecessor = None
while root is not None:
if root.left is not None:
# predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止
predecessor = root.left
while predecessor.right is not None and predecessor.right != root:
predecessor = predecessor.right
# 让 predecessor 的右指针指向 root,继续遍历左子树
if predecessor.right is None:
predecessor.right = root
root = root.left
# 说明左子树已经访问完了,我们需要断开链接
else:
res.append(root.val)
predecessor.right = None
root = root.right
# 如果没有左孩子,则直接访问右孩子
else:
res.append(root.val)
root = root.right
return res
思路解析(解法三)
- 核心:Morris 遍历利用树中大量
None的右指针,临时改成指向后继,从而在不使用栈、不递归的情况下回到「父结点」;遍历结束再恢复为None,故又称线索二叉树思路。 - 前驱
predecessor:当前root若有左子树,则前驱为「从左孩子出发,沿右孩子一直走到尽头」的结点(且predecessor.right不能已是当前root,避免环上误判)。 - 两种情况:若
predecessor.right is None,说明第一次来到该子树,暂时predecessor.right = root建线索,并进入root.left;若predecessor.right == root,说明左子树已按中序走完,此时访问root.val,拆掉线索predecessor.right = None,再进入root.right。 - 无左孩子:当前结点在中序里轮到访问,记入
res后走右子。 - 复杂度:时间 O(n)(每个结点被访问常数次,线索建立与拆除摊还);额外空间 O(1)(仅若干指针),优于递归与栈版的空间。
LeetCode 104. 二叉树的最大深度 ↑
题目
给定一个二叉树 root,返回其最大深度。
二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。
提示
- 树中节点的数量在
[0, 10^4]区间内 -100 ≤ Node.val ≤ 100
代码(Python)解法一:递归
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def maxDepth(self, root):
"""
:type root: Optional[TreeNode]
:rtype: int
"""
if root == None:
return 0
return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
思路解析(解法一)
- 递归含义:
maxDepth(root)表示以root为根的子树的最大深度(按结点个数计)。 - 空树:
root is None时深度为 0。 - 转移:当前树深度 = 左右子树深度的较大值 + 1(根结点本身占一层)。
- 复杂度:每个结点访问一次,时间 O(n);递归栈最坏 O(n)(链状树),平均 O(h),h 为树高。
代码(Python)解法二:广度优先搜索(层序)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
from collections import deque
class Solution:
def maxDepth(self, root):
if root is None:
return 0
queue = deque()
queue.append(root)
ans = 0
while queue:
sz = len(queue)
while sz > 0:
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
sz -= 1
ans += 1
return ans
思路解析(解法二)
- 核心:按层扩展。队列中始终保存当前层的全部结点;每处理完一层,
ans += 1,深度即层数。 - 内层循环:
sz = len(queue)固定本层结点个数,依次popleft并把非空左右孩子入队,避免与下一层混在一起。 - 与递归对比:递归是「先到底再回溯计深度」;BFS 是「横向扫一层层数」,语义直观。
- 复杂度:每个结点入队、出队各一次,时间 O(n);队列最多存一层的结点,最坏 O(n)(完全二叉树最宽一层),平均 O(w),w 为最大层宽。

浙公网安备 33010602011771号