树的最低公共祖先
讨论区较快的解答:
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);
return left==null? right: right==null? left: root;
}
与上述思路一样但是易懂的解法(也更快6ms)
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return lowestCommonAncestorRecursive(root, p, q);
}
public TreeNode lowestCommonAncestorRecursive(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
if (root == p || root == q) {
return root;
}
TreeNode left = lowestCommonAncestorRecursive(root.left, p, q);
TreeNode right = lowestCommonAncestorRecursive(root.right, p, q);
if (left != null && right != null) {
return root;
}
return left != null ? left : right;
}
自创的沙雕解法(110ms)思路:中序遍历的思路正好可以先遍历左根右。因此可根据中序遍历结果中各节点的相对顺序确定最低祖先所在位置。
缺点:1.需提前遍历一遍树并将顺序存储,浪费了存储空间与时间
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
ArrayList<TreeNode> inorder= new ArrayList<>();
inorder(root,inorder);
TreeNode res= searchAncestor(inorder,root,p,q);
// for(TreeNode tmp: inorder){
// System.out.print(tmp.val+" ");
// }
return res;
}
public void inorder(TreeNode root, ArrayList<TreeNode> inorder){
if(root==null) return;
inorder(root.left,inorder);
inorder.add(root);
inorder(root.right,inorder);
}
public TreeNode searchAncestor(ArrayList<TreeNode> inorder,TreeNode root,TreeNode p,TreeNode q){
int ri= inorder.indexOf(root), pi= inorder.indexOf(p), qi= inorder.indexOf(q);
if(pi>=ri && qi<=ri || pi<=ri && qi>=ri )
return root;
if(pi>ri && qi>ri)
return searchAncestor(inorder,root.right,p,q);
// if(pi<=ri && qi<=ri)
return searchAncestor(inorder,root.left,p,q);
// return null;
}