Sword refers to Offer 68-I/68-II Binary search tree nearest common ancestor/Binary tree nearest common ancestor C++


2021/2/6 Second Brush
finally ended the second brush trip, and three brush half of the problem.
The recursion is much better than before. The last three consecutive judgments about 68-II have been written in a new way, which seems to be easier to understand.


class Solution {
    
    
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
        if(root == NULL) return NULL;
        //如果自己就是所找的结点返回自己
        if(root == p || root == q) return root;
        TreeNode* left = lowestCommonAncestor(root -> left, p, q);
        TreeNode* right = lowestCommonAncestor(root -> right, p,q);
        if(left != NULL && right != NULL) return root;
        if(left == NULL) return right;
        if(right == NULL) return left;
        return NULL;
    }
};

68-I

Title description

Insert picture description here

Solution recursion

First of all, we must understand the so-called nearest common ancestor, which is the node where the two nodes are divided into the left and right subtrees for the first time . Then we can obviously know that all the nodes of the left subtree of the binary search tree are smaller than the root node. Point, all nodes of the right subtree are greater than the root node.
So for a node p,
Insert picture description here
you can get the code after a little thought

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
        while(root) {
    
    
            if(root -> val < p -> val && root -> val < q -> val) root = root -> right;
            else if(root -> val > p -> val && root -> val > q -> val) root = root -> left;
            else break;
        }
        return root;
    }
};

Insert picture description here
The time complexity is O(N), and the binary search tree degenerates to a linked list. The
space complexity is O(1)

68-II

Title description

Insert picture description here

Post-solution traversal

As the last question of Jianzhi's offer, I did not disappoint---a rare batch. As we all know, simple questions of Jianzhi are more difficult than medium ones.
First of all, the things we solved have not changed. The two nodes were separated into the node of the left and right subtrees for the first time ,
and then let's just look at the ideas.
For each node, post-order traversal can guarantee to execute its own function body after considering the left and right subtrees.  What we need to know is whether p/q is in its left subtree or right subtree, or not.
If you don’t understand, you can go to this dynamic picture to go through the solution of the big guy’s problem by yourself

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    
    
        //后序遍历中遇到p或者q或者已经到头还没遇到p、q
        if(root == NULL || root == p || root == q) return root;
        TreeNode *right = lowestCommonAncestor(root -> right, p, q);
        TreeNode *left = lowestCommonAncestor(root -> left, p, q);
        //右子树和左子树都找不到p或者q
        if(right == NULL && left == NULL) return NULL;
        //左子树找不到右子树找到了,继续往左子树找,返回左子树最终是否找到的结果
        else if(left == NULL) return right;
        //右子树找不到左子树找到了,继续往右子树找,返回右子树最终是否找到的结果
        else if(right == NULL) return left;
        //左右都不为空,说明根结点就是最近公共结点
        return root;
    }
};

Insert picture description here
Time complexity O(N)
Space complexity O(N)

Guess you like

Origin blog.csdn.net/qq_42883222/article/details/112854532