树与图中等3 种解法
#235二叉搜索树的最近公共祖先
在二叉搜索树中寻找两个给定节点的最近公共祖先。
#二叉搜索树#深度优先搜索#路径
解题主线
01
若 p、q 同在当前值一侧就继续向该侧走,否则当前节点就是分叉点。
解法 1:递归利用 BST
根据两个目标相对根的位置递归进入唯一可能的子树。
时间复杂度
O(h)
空间复杂度
O(h)
java
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return null;
if (p.val < root.val && q.val < root.val) {
return lowestCommonAncestor(root.left, p, q);
}
if (p.val > root.val && q.val > root.val) {
return lowestCommonAncestor(root.right, p, q);
}
return root;
}
}根据两个目标相对根的位置递归进入唯一可能的子树。
解法 2:迭代寻找分叉点
沿 BST 单路径移动,直到两个目标位于两侧或命中当前节点。
时间复杂度
O(h)
空间复杂度
O(1)
java
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode current = root;
while (current != null) {
if (p.val < current.val && q.val < current.val) current = current.left;
else if (p.val > current.val && q.val > current.val) current = current.right;
else return current;
}
return null;
}
}沿 BST 单路径移动,直到两个目标位于两侧或命中当前节点。
解法 3:比较根到节点路径
分别生成根到 p、q 的路径,最后一个相同节点即最近公共祖先。
时间复杂度
O(h)
空间复杂度
O(h)
java
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
List<TreeNode> first = pathTo(root, p);
List<TreeNode> second = pathTo(root, q);
TreeNode answer = null;
for (int i = 0; i < Math.min(first.size(), second.size()); i++) {
if (first.get(i) != second.get(i)) break;
answer = first.get(i);
}
return answer;
}
private List<TreeNode> pathTo(TreeNode root, TreeNode target) {
List<TreeNode> path = new ArrayList<>();
TreeNode current = root;
while (current != null) {
path.add(current);
if (current == target) break;
current = target.val < current.val ? current.left : current.right;
}
return path;
}
}分别生成根到 p、q 的路径,最后一个相同节点即最近公共祖先。
边界与易错点
- 比较的是 p、q 的值与当前节点值,不是只比较 p 和 q。
- 组合文件与独立文件的重复递归、迭代实现需合并。
整理来源
由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。
leetcode/src/main/java/tree/Q235_236_lowestCommonAncestor.javaleetcode/src/main/java/tree/Q235_bst_lowestCommonAncestor.java