The nearest common ancestor of the binary tree, the nearest common ancestor of the binary search tree (the same idea)

The nearest common ancestor of the binary tree


题目Linking
  the nearest common ancestor of a binary tree
  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 a 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:
insert image description here

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The nearest common ancestor of node 5 and node 1 is Node 3.

Example 2:
insert image description here

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The nearest common ancestor of nodes 5 and 4 is Node 5. Because by definition the nearest common ancestor node can be the node itself

Method 1 (time complexity O(N^2))

Given a binary tree, two nodes, p and q, are given in this binary tree.
There are three situations
  . Case 1: Both the p node and the q node are in the left subtree. At this time, the nearest common ancestor is also in the left subtree. Continue to discuss the situation. Case
  2: Both the p node and the q node are in the right subtree. The common ancestor is also in the right subtree. Continue to discuss
  the situation 3: one of the p node and the q node is in the left subtree, and the other is in the right subtree. At this time, the root of this tree is the nearest common node. Special case: if the p node
  or One of the q nodes is the root node, at this time the nearest common ancestor is the root node
Use recursion to decompose sub-problems

insert image description here
insert image description here

The essence of problem-solving is to recursively call to solve sub-problems, and divide the original problem into sub-problems

class Solution {
    
    
public:
    bool Find(TreeNode* root, TreeNode* val)
    {
    
    
        if (root == NULL)return false;
		
        return root == val || Find(root->left, val) || Find(root->right, val);
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
    	//判断特殊情况,根节点为空
        if (root == NULL)return NULL;
        //特殊情况,p节点或者q节点其中一个为根节点,此时最近公共祖先就是根节点
        if (root == p || root == q)return root;
		//用来判断p和q在左右子树位置的变量
        bool pInLeft, pInRight, qInLeft, qInRight;
        pInLeft = Find(root->left, p);
        pInRight = !pInLeft;
        qInLeft = Find(root->left, q);
        qInRight = !qInLeft;

        if(pInLeft && qInLeft)
        {
    
    
        	//情况1:p和q都在左子树,递归调用根节点的左子树
            return lowestCommonAncestor(root->left,p,q);
        }else if(pInRight&& qInRight)
        {
    
    
        	//情况2:p和q都在右子树,递归调用根节点的右子树
            return lowestCommonAncestor(root->right,p,q);
        }else{
    
    
        	//p和q,一个在左子树,一个在右子树,此时根节点为最近公共祖先
            return root;
        }
    }
};

Method 2 (time complexity O(N))

Find the path method, record the p node and q node path of the

binary tree, and convert it into a linked list
to find the common node problem. Node: No matter what the situation is, put the node into the stack first, and judge whether the newly entered node is a p node. If it is not a p node, search in the left subtree of p. If the left subtree is not found, go to the right subtree to check it. The right subtree is not found either, and this node is popped out of the stack until the p node is found. The q node is the same

code:

class Solution {
    
    
public:
    bool FindPath(TreeNode* root,TreeNode* x,stack<TreeNode*>& path)
    {
    
    
        //访问到空节点,返回false
        if(root==nullptr)return false;
        //不管什么情况,先将当前节点入栈
        path.push(root);
        //判断当前节点是否为要查找节点
        if(root==x)return true;
        //递归左子树查找
        if(FindPath(root->left,x,path))
        {
    
    
            return true;
        }
        //递归右子树查找
        if(FindPath(root->right,x,path))
        {
    
    
            return true;
        }
        //左右子树以及根节点都不是要查找的节点,则将该节点出栈
        path.pop();
        return false;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
        stack<TreeNode*> ppath; //记录p节点路径的栈
        FindPath(root,p,ppath);
        stack<TreeNode*> qpath; //记录q节点路径的栈
        FindPath(root,q,qpath);

        //将快的路径先走
        while(ppath.size()>qpath.size())ppath.pop();
        while(ppath.size()<qpath.size())qpath.pop();
        //第一个相同的节点就是最近公共祖先
        while(ppath.top()!=qpath.top())
        {
    
    
            ppath.pop();
            qpath.pop();
        }
        return qpath.top();
    }
};

The nearest common ancestor of a binary search tree


题目Linking
  the nearest common ancestor of a binary search tree
  Given a binary search 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 a 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 node can also be its own ancestor)."
  For example, given the following binary search tree: root = [6,2,8,0,4,7,9,null,null,3,5]

Example 1:
insert image description here

Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The nearest common ancestor of nodes 2 and 8 is 6.

Example 2:

Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
Output: 2
Explanation: The nearest common ancestor of nodes 2 and 4 is 2, because by definition the nearest common ancestor node can be the node itself.

The idea is the same as above, but the nearest common ancestor of the binary tree needs to find the positions of p and q for recursive calls.
Due to the special nature of the binary search tree, we don't need to manually find the positions of p and q, just judge the size. The nature of the fork search tree, the left subtree element of the root node is smaller than the root node, and the left subtree element of the root node is larger than the root node.

class Solution {
    
    
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
        if(root==NULL)return NULL;
        if(p==root||q==root)return root;
        if(p->val>root->val&&q->val>root->val)
        {
    
    
            //都在右子树
            return lowestCommonAncestor(root->right,p,q);
        }else if(p->val<root->val&&q->val<root->val)
        {
    
    
        	//都在左子树
            return lowestCommonAncestor(root->left,p,q);
        }else{
    
    
        	//一个在左,一个在右
            return root;
        }
    }
};

Guess you like

Origin blog.csdn.net/Tianzhenchuan/article/details/132053949