Leetcode problem solution 236-nearest common ancestor of 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 and q of the rooted tree T, the nearest common ancestor is expressed as a node x, satisfying that x is the ancestor of p and q and the depth of x is as large as possible (a A node can also be its own ancestor)."

Example 1:

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

Example 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。

Example 3:

输入:root = [1,2], p = 1, q = 2
输出:1

prompt:

树中节点数目在范围 [2, 105] 内。
-109 <= Node.val <= 109
所有 Node.val 互不相同 。
p != q
p 和 q 均存在于给定的二叉树中。

Problem-solving ideas:

The idea of ​​the problem solution is referenced from https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/solution/236-er-cha-shu-de-zui-jin-gong-gong -zu-xian-hou-xu/ The definition of
nearest common ancestor : Let node root be a common ancestor of node p, q, if its left child node root.left and right child node root.right are not common to p, q Ancestor, then said root is "the nearest common ancestor" .

According to the above definition, if root is the nearest common ancestor of p, q, it can only be one of the following:

p and q are in the root's subtree, and separate the opposite sides of root (that is, in the left and right subtrees respectively) ;
p = root, and q is in the root's left or right subtree;
q = root, and p is in the left or right subtree of root;

Insert picture description here
Consider post-order traversal of the binary tree through recursion, and return when it encounters node p or q. Backtracking from bottom to top, when the nodes p, q are on the opposite side of the node root, the node root is the nearest common ancestor, and it returns to the root upwards.

Recursive analysis:
termination conditions:

  • When the leaf node is crossed, null is directly returned;
  • When root is equal to p, q, then directly return to root;

Recursive work:

  • Turn on the recursive left child node, and the return value is recorded as left;
  • Turn on the recursive right child node, and the return value is recorded as right;

Return value: According to left and right, it can be expanded into four situations;

  • When left and right are empty at the same time: it means that the left/right subtrees of root do not contain p, q, and null is returned;
  • When left and right are not empty at the same time: indicating that p and q are listed on the opposite side of root (respectively in the left/right subtree), so root is the nearest common ancestor, return to root;
  • When left is empty, right is not empty: both p and q are not in the left subtree of root, and return right directly. Specifically, it can be divided into two situations: one of
    p and q is in the right subtree of root, at this time right points to p (assumed to be p);
    both nodes of p and q are in the right subtree of root, at this time right Point to the nearest common ancestor node;
  • When left is not empty, rightr is empty: the same as in case 3.

Observation found that situation 1. can be combined into 3. and 4.

Implementation code

class Solution {
    
    
    public TreeNode SearchAncester(TreeNode root,TreeNode p, TreeNode q){
    
    
        //如果root为空,那么直接返回空
        if(root==null){
    
    
            return null;
        }
        //如果root为p结点或者q结点,那么就返回root
        if(root==p || root==q){
    
    
            return root;
        }else{
    
    
            //在左子树和右子树中寻找p,q
            TreeNode leftNode=SearchAncester(root.left,p,q);
            TreeNode rightNode=SearchAncester(root.right,p,q);
            //左子树为空,说明在右子树中,如果最终右子树也为空,那么直接返回空
            if(leftNode==null){
    
    
                return rightNode;
            //右子树为空,说明在左子树中
            }else if(rightNode==null){
    
    
                return leftNode;
            }else{
    
    
            //如果左右子树都不为空,那么最近公共祖先结点就是root
                return root;
            }
        }
    }
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    
    
        if(root==null){
    
    
            return root;
        }
        return SearchAncester(root,p,q);
    }
}

Guess you like

Origin blog.csdn.net/qq_39736597/article/details/114630436