最近公共祖先(Lowest Common Ancestor)
TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)
function lowestCommonAncestor(root, p, q) { // p,q一定在以root为根的树上
if(root === null) return null
if(root == p || root === q) return root
const left = lowestCommonAncestor(root.left, p, q)
const right = lowestCommonAncestor(root.right, p, q)
// 情况1,
if(left === null && right === null) return null
if(left === null) return right
if(right === null) return left
return root
};
function lowestCommonAncestor(root, p, q) {
return find(root, p.val, q.val)
function find(root, val1, val2) {
if(root === null) return null
if(root.val ===val1 || root.val === val2){ // 前序位置,找到LCA
return root
}
const left = find(root.left, val1, val2)
const right = find(root.right, val1, val2)
if(left !== null && right !== null) return root
return left !=null ? left : right
}
}
- 输入一棵不含重复值的二叉树,输入一个包含若干节点的列表nodes(这些节点都存于二叉树中)
TreeNode lowestCommonAncestor(TreeNode root, TreeNode[] nodes);
function lowestCommonAncestor(root, nodes) {
let values = []
for(let node of nodes) {
values.push(node.val)
}
return find(root, values)
function find (root, values) {
if(root === null) return null
if(values.inclues(root.val) return root
const left = find(root.left, values)
const right = find(root.right, values)
if(left !== null && right !=== null) return root // 当前节点是LCA
return left !== null ? left : right
}
}
- 输入一棵不含重复值的二叉树,以及2个节点p,q,如果p,q不存于树中,则返回空指针
function lowestCommonAncestor() {
const foundP = false, foundQ = false
function find(root, val1, val2) {
if(root ===null) return null
const left = find(root.left, p, q)
const right = find(root.right, p, q)
if(left !==null && right !==null ) return root
// 用来判断p,q是否都在树中
if(root.val === val || root.val === right) {
if(root.val === val){ foundP = true }
if(root.val === val){ foundQ = true }
return root
}
if(left !== null) return left
if(right !== null) return right
}
const res = find(root,p.val, q.val)
if(!foundP || !foundQ) return null
return res
}
- 二叉搜索树
假设val1 < val2,那么val1 <= root.val <= val2则说明当前节点就是LCA;
若root.val比val1还小,则需要去值更大的右子树寻找LCA;
若root.val比val2还大,则需要去值更小的左子树寻找LCA
- 节点中包含其根节点
class Node {
int val;
Node left;
Node right;
Node parent; 「把parent想象成next节点」
};
Node lowestCommonAncestor(Node p, Node q);
function lowestCommonAncestor(p, q) {
let p1 = p, p1 = q
while(p1 != p2) {
if(p1 === null) {
p1 = q
}else {
p1 = p1.parent
}
if(p2 === null) {
p2 = p // 交换
}else {
p2 = p2.parent // 向前走一步
}
}
return p1
}