Java finds the nearest common ancestor of two nodes of a binary tree

The nearest common ancestor of the binary tree

Problem Description

Given a binary tree, find the nearest common ancestor of two specified nodes in the tree.
The definition of the nearest common ancestor in Baidu Encyclopedia is:

"For two nodes p, q of a rooted tree T, the nearest common ancestor is represented as a node x, satisfying that x is the ancestor of p, q and the depth of x is as large as possible (a node can also be its own ancestor). "

example

insert image description hereinsert image description hereinsert image description here

Original title OJ link

https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/submissions/

answer code

method one

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    
    
        if(root == null){
    
    //如果是一颗空树,那么也就没有什么祖先结点的说法了
            return null;
        }
        if(root == p || root == q){
    
    //p,q其中一个是根节点,那么祖先就是根节点
        //这一行代码也是用来递归寻找p,q结点的   3
            return root;
        }
        //往左子树去找p,q结点
        TreeNode leftRet = lowestCommonAncestor(root.left,p,q);
        //往右子树去找p,q结点
        TreeNode rightRet = lowestCommonAncestor(root.right,p,q);

        if(leftRet != null && rightRet != null){
    
     
            return root;//说明pq分布分布在root的左右两边,那么他们的公共结点一定是root结点  1
        }
        else if(leftRet != null){
    
    
            return leftRet;//说明pq都分布在根节点左边,那么一直往下找,无论pq谁先被找到谁就是祖先结点   2
        }
        else if(rightRet != null){
    
    
            return rightRet;//说明pq都分布在根节点右边边,那么一直往下找,无论pq谁先被找到谁就是祖先结点
        }
        //最后一种情况,就是qp根本没有公共祖先
        return null;      
    }
}

The following figure is the situation of the above code 1
insert image description here

The following figure is the situation of the above code 2

insert image description hereThe following figure is the situation of the above code 3
insert image description here

Method Two

In addition, the path from the root node to the q and p nodes can be found first, and then stored in a linked list, and then it becomes a problem of finding the common node of the two linked lists.
But this idea has a problem to be solved, that is, how to find the path from the root node of the path to a certain node. The method is to use the stack to first push a node that is not sure whether it is on the path, and then traverse its subtree If no target node is found, confirm that the node is not on the path, and then pop up again. In fact, it is depth-first traversal.
The specific code is as follows

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.Deque;
import java.util.LinkedList;
class Solution {
    
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    
    
        Deque<TreeNode> stack1 = new LinkedList<>();
        getPath(root,p,stack1);
        Deque<TreeNode> stack2 = new LinkedList<>();
        getPath(root,q,stack2);

        //判断栈的大小
        int length1 = stack1.size();
        int length2 = stack2.size();
        int length = 0;
        if(length1>length2){
    
    
            length = length1 - length2;
            while(length != 0){
    
    
                stack1.pop();
                length--;
            }
        }
        else{
    
    
            length = length2 - length1;
            while(length != 0){
    
    
            stack2.pop();
            length--;
            }
        }
        //栈元素个数都一样了
        while(!stack1.isEmpty() && !stack2.isEmpty()){
    
    
            if(stack1.peek() != stack2.peek()){
    
    
                stack1.pop();
                stack2.pop();
            }
            else{
    
    
                return stack1.peek();
            }
        
        }
        return null;    
        
    }
    public  Boolean getPath(TreeNode root,TreeNode node,Deque<TreeNode> stack){
    
    
        if(root == null || node == null){
    
    
            return false;
        }
        stack.push(root);//根节点肯定在路径里面,第一个压入栈中,
        if(root == node){
    
    
            return true;
        }
        boolean ret1 = getPath(root.left,node,stack);//之后先把寻找过程中的结点都先压入栈中
        if(ret1 == true){
    
    
            return true;//往左边找找到了
        }
        boolean ret2 = getPath(root.right,node,stack);
        if(ret2 == true){
    
    
            return true;//往右边找找到了
        }
        //往左和往右都没找到,说明这个结点不在路径上,所以把这个点给弹出
        stack.pop();
        return false;
        
    }
}

Guess you like

Origin blog.csdn.net/baixian110/article/details/130954588