二叉树的中序遍历
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:

输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
解法及思路
三种遍历顺序:
前序:根 → 左 → 右 中序:左 → 根 → 右 后序:左 → 右 → 根
中序遍历:先遍历左子树,再访问根,最后遍历右子树。
递归(最简洁)
二叉树:
1 / \ 2 3 / \ 4 5
调用 inorder(1, result):
inorder(1) ├─ inorder(2) │ ├─ inorder(4) │ │ ├─ inorder(null) → 返回 │ │ ├─ result.add(4) → result=[4] │ │ └─ inorder(null) → 返回 │ ├─ result.add(2) → result=[4, 2] │ └─ inorder(5) │ ├─ inorder(null) → 返回 │ ├─ result.add(5) → result=[4, 2, 5] │ └─ inorder(null) → 返回 ├─ result.add(1) → result=[4, 2, 5, 1] └─ inorder(3) ├─ inorder(null) → 返回 ├─ result.add(3) → result=[4, 2, 5, 1, 3] └─ inorder(null) → 返回 最终:result = [4, 2, 5, 1, 3]
java
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
inorder(root, result);
return result;
}
private void inorder(TreeNode node, List<Integer> result) {
if (node == null) return;
inorder(node.left, result); // 左
result.add(node.val); // 根
inorder(node.right, result); // 右
}
}
二叉树的最大深度
给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:3
示例 2:
输入:root = [1,null,2]
输出:2
解法及思路
递归
最大深度 = 1 + max(左子树深度, 右子树深度)
depth(root) = 1 + max(depth(root.left), depth(root.right)) 终止条件:root == null,返回 0
二叉树:
3 / \ 9 20 / \ 15 7
递归计算:
depth(3) = 1 + max(depth(9), depth(20)) = 1 + max(1, depth(20)) = 1 + max(1, 1 + max(depth(15), depth(7))) = 1 + max(1, 1 + max(1, 1)) = 1 + max(1, 2) = 1 + 2 = 3
翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
示例 1:

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
示例 2:

输入:root = [2,1,3]
输出:[2,3,1]
示例 3:
输入:root = []
输出:[]
解法及思路
递归
对每个节点,交换它的左右子树。
1. 终止条件:root == null,返回 null 2. 交换 root.left 和 root.right 3. 递归翻转左子树 4. 递归翻转右子树 5. 返回 root
二叉树:
4 / \ 2 7 / \ / \ 1 3 6 9
递归翻转:
第1步:交换4的左右子树 4 / \ 7 2 / \ / \ 6 9 1 3 第2步:交换7的左右子树 4 / \ 7 2 / \ / \ 9 6 1 3 第3步:交换2的左右子树 4 / \ 7 2 / \ / \ 9 6 3 1 结果: 4 / \ 7 2 / \ / \ 9 6 3 1
java
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root==null) return null;
//交换左右子树
TreeNode temp=root.right;
root.right=root.left;
root.left=temp;
//递归翻转左右子树
invertTree(root.left);
invertTree(root.right);
return root;
}
}
对称二叉树
给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false
解法及思路
递归比较左右子树
对称的条件:
左子树的左 和 右子树的右 对称 左子树的右 和 右子树的左 对称
即:
compare(left, right): 1. left 和 right 都为空 → true 2. left 或 right 一个为空 → false 3. left.val != right.val → false 4. 递归比较: compare(left.left, right.right) compare(left.right, right.left)
对称的树:
1 / \ 2 2 / \ / \ 3 4 4 3 比较: 2 和 2:相等 ✅ 2.left=3 和 2.right=3:相等 ✅ 2.right=4 和 2.left=4:相等 ✅ 3.left=null 和 3.right=null:相等 ✅ 4.left=null 和 4.right=null:相等 ✅ ... 结果:true
不对称的树:
1 / \ 2 2 \ \ 3 3 比较: 2 和 2:相等 ✅ 2.left=null 和 2.right=3:一个空一个非空 ❌ 结果:false
java
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null) return true;
return compare(root.left,root.right);
}
public boolean compare(TreeNode left,TreeNode right){
//都为空
if(left==null && right==null) return true;
//一个为空
if(left==null || right==null) return false;
//值不相等
if(left.val!=right.val) return false;
//递归比较
return compare(left.left,right.right) && compare(left.right,right.left);
}
}
二叉树的直径
给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。
两节点之间路径的 长度 由它们之间边数表示。
示例 1:

输入:root = [1,2,3,4,5]
输出:3
解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。
示例 2:
输入:root = [1,2]
输出:1
解法及思路
递归计算深度
关键:直径 = 左子树深度 + 右子树深度
对于每个节点: 左子树深度 = depth(left) 右子树深度 = depth(right) 经过该节点的直径 = 左深度 + 右深度 全局直径 = max(所有节点的直径)
二叉树:
1 / \ 2 3 / \ 4 5
计算每个节点的直径:
节点4:左深度0 + 右深度0 = 0 节点5:左深度0 + 右深度0 = 0 节点2:左深度1 + 右深度1 = 2 节点3:左深度0 + 右深度0 = 0 节点1:左深度2 + 右深度1 = 3 最大直径 = 3
java
class Solution {
private int maxlength=0;
public int diameterOfBinaryTree(TreeNode root) {
depth(root);
return maxlength;
}
private int depth(TreeNode node){
if(node==null) return 0;
int leftlength=depth(node.left);
int rigthlength=depth(node.right);
int length=leftlength+rigthlength;
// 更新最大直径
maxlength=Math.max(length,maxlength);
// 返回当前节点的深度
return 1+Math.max(leftlength,rigthlength);
}
}
二叉树的层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
解法及思路
BFS + 队列
用队列逐层遍历:
1. 根节点入队 2. 每次处理当前层的所有节点 3. 把下一层的节点入队 4. 重复直到队列为空
二叉树:
3 / \ 9 20 / \ 15 7
初始:queue = [3] 第1层: 处理3,把9和20入队 result = [[3]] queue = [9, 20] 第2层: 处理9,无子节点 处理20,把15和7入队 result = [[3], [9, 20]] queue = [15, 7] 第3层: 处理15,无子节点 处理7,无子节点 result = [[3], [9, 20], [15, 7]] queue = [] 结束
java
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result=new ArrayList<>();
if(root==null) return result;
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size=queue.size();// 当前层的节点数
List<Integer> level=new ArrayList<>();
// 处理当前层的所有节点
for(int i=0;i<size;i++){
TreeNode node=queue.poll();
level.add(node.val);
// 下一层入队
if(node.left!=null) queue.offer(node.left);
if(node.right!=null) queue.offer(node.right);
}
result.add(level);
}
return result;
}
}
二叉树的最近公共祖先
236. 二叉树的最近公共祖先 - 力扣(LeetCode)
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:"对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。"
示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 `5 `和节点 `1 `的最近公共祖先是节点 `3 。`
示例 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 `5 `和节点 `4 `的最近公共祖先是节点 `5 。`因为根据定义最近公共祖先节点可以为节点本身。
示例 3:
输入:root = [1,2], p = 1, q = 2
输出:1
解法及思路
递归
对于每个节点,判断 p 和 q 是否在它的子树中。
1. 如果 node 是 p 或 q,返回 node 2. 递归左子树,得到 left 3. 递归右子树,得到 right 4. 如果 left 和 right 都不为空,说明 p 和 q 分别在两边,node 就是 LCA 5. 如果 left 为空,返回 right 6. 如果 right 为空,返回 left
二叉树:
3 / \ 5 1 / \ / \ 6 2 0 8 / \ 7 4
情况1:p=5, q=1
递归到3: 左子树返回5(找到p) 右子树返回1(找到q) left 和 right 都不为空 → 3就是LCA ✅
情况2:p=5, q=4
递归到3: 左子树递归到5: 左子树递归到6:返回null 右子树递归到2: 左子树递归到7:返回null 右子树递归到4:返回4(找到q) → 2的右子树返回4,左子树null → 返回4 → 5的左子树null,右子树返回4 → 5本身就是p,返回5 → 3的左子树返回5 右子树递归到1: 返回null(p和q都不在) → 3的左子树返回5,右子树null → 返回5 → 5就是LCA ✅
java
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//终止条件
if(root==null||root==p||root==q){
return root;
}
//递归左右子树
TreeNode left=lowestCommonAncestor(root.left,p,q);
TreeNode right=lowestCommonAncestor(root.right,p,q);
//左右都不为空,说明pq分别在两边
if(left!=null&&right!=null){
return root;
}
//返回非空的那个
return (left!=null)?left:right;
}
}
验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含严格小于当前节点的数。
- 节点的右子树只包含 严格大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:

输入:root = [2,1,3]
输出:true
示例 2:

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
解法及思路
中序遍历
BST 的中序遍历是严格递增的。
中序遍历:左 → 根 → 右 如果是BST,结果一定是升序
所以:中序遍历,检查是否严格递增。
BST:
2 / \ 1 3 中序遍历:[1, 2, 3] → 递增 ✅
非BST:
5 / \ 1 4 / \ 3 6 中序遍历:[1, 5, 3, 4, 6] → 3 < 5,不递增 ❌
java
class Solution {
private long prev = Long.MIN_VALUE; // 记录前一个节点的值
public boolean isValidBST(TreeNode root) {
if(root==null) return true;
//左
if (!isValidBST(root.left)) return false;
// 根:检查是否 > prev
if (root.val <= prev) return false;
prev = root.val;
// 右
return isValidBST(root.right);
}
}