Programmer's Question selection 100 questions (48)-Two fork tree two nodes of the lowest common parent node [data structure]_ sword means an offer.

Source: Internet
Author: User

Topic: The node of the two fork tree is defined as follows:

struct TreeNode

{

int m_nvalue;

treenode* M_pleft;

treenode* M_pright;

};

Enter two nodes in the binary tree to output the lowest common parent node of the two nodes in the number.

Analysis: Finding the lowest common node of two nodes in a number of points is a frequent problem in the interview. There are at least two variants of this problem.

The first variant is a two-fork tree is a special two-fork tree: Looking for a binary tree. That is, the tree is sorted, the node located on the left subtree is smaller than the parent node, and the node in the right subtree is larger than the parent node. We just need to start with the root node and compare two nodes. If the value of the current node is greater than the two nodes, then the lowest common parent node must be in the left subtree of the current node. If the value of the current node is smaller than the two nodes, then the lowest common parent node must be in the right subtree of the current node.

The second variant is that the tree is not necessarily a two-forked tree, and each node has a pointer to its parent node. So we can start from any node and get a one-way list that reaches the root node. So this problem is converted to the first public node of two one-way lists. We discussed this issue in question 35th in our series.

Now we go back to the question itself. The so-called common parent node is that two nodes appear in the subtree of this node. So we can define a function to determine whether another node is included in the subtree of a node. This is not a very difficult thing, we can use the recursive method to achieve:

//If the tree with head phead Has a node pnode, return True.
otherwise return false.
bool Hasnode (treenode* Phead, treenode* pnode)
{
    if (Phead = = Pnode) return
        true;
 
    BOOL has = false;
 
    if (phead->m_pleft!= NULL)
        has = Hasnode (Phead->m_pleft, pnode);
 
    if (!has && phead->m_pright!= NULL)
        has = Hasnode (Phead->m_pright, pnode);
 
    return has;
}


We can start with the root node to determine whether the left and right subtree in the tree rooted at the current node contains the two nodes we are looking for. If two nodes appear in its left subtree, the lowest common parent node also appears in its left subtree. If two nodes appear in its right subtree, the lowest common parent node also appears in its right subtree. If two nodes appear in the left subtree and one appears in the right subtree, the current node is the lowest common parent node. Based on this idea, we can write the following code:

Find the last parent of PNode1
And PNode2 in a, with head phead/////////////////////////////////////////////////////////////////////////////////  treenode* lastcommonparent_1 (treenode* phead, treenode* pNode1, treenode* pNode2) {if (Phead = null | | pNode1 = NULL ||
 
    PNode2 = null) return null;
    Check whether left child has pNode1 and pNode2 bool leftHasNode1 = false;
    BOOL LeftHasNode2 = false;
        if (phead->m_pleft!= NULL) {leftHasNode1 = Hasnode (Phead->m_pleft, pNode1);
    LeftHasNode2 = Hasnode (Phead->m_pleft, PNode2); } if (LeftHasNode1 && leftHasNode2) {if phead->m_pleft = PNode1 | | phead->m_pleft = = Pnod
 
        E2) return phead;
    Return lastcommonparent_1 (Phead->m_pleft, PNode1, PNode2);
   }//Check whether right child has pNode1 and pNode2 bool rightHasNode1 = false; BOOL RightHasNode2 = false; if (phead->m_pright!= NULL) {if (!lefthasnode1) rightHasNode1 = Hasnode (Phead->m_pright, PNo
        DE1);
    if (!lefthasnode2) RightHasNode2 = Hasnode (Phead->m_pright, PNode2); } if (RightHasNode1 && rightHasNode2) {if (Phead->m_pright = = PNode1 | | phead->m_pright = =
 
        PNODE2) return phead;
    Return lastcommonparent_1 (Phead->m_pright, PNode1, PNode2); if (leftHasNode1 && rightHasNode2) | |
        (LeftHasNode2 && rightHasNode1))
 
    return phead;
return NULL; }


Then we will analyze the efficiency of this method. The essence of function hasnode is to traverse a tree whose time complexity is O (n) (n is the number of nodes in the tree). Because we start with a node, call function Hasnode for each node. The total time complexity is therefore O (N2).

By carefully analyzing the code above, it is not difficult to find out whether a tree with a node as its root contains a node that needs to traverse each node of the tree. Next we judge whether the Zoozi node or the tree with the right node as root contains the node to find, and still need to traverse it. The second traversal is actually done in front of the first traversal. Because of the repeated traversal, this method is certainly not the best in time efficiency.

We mentioned earlier that if there is a pointer to the parent node in the node, we can turn the problem into a common node for two lists. Now we can find a way to get this list. We have analyzed how to get a path to the beginning of the root node in the 4th question in this question series. We can change here a little bit:

//Get the path form Phead and Pnode in A and head phead
//////////////////////////////////////////////////////////////////////////////// /
bool Getnodepath (treenode* phead, treenode* pnode, std::list<treenode*>& path)
{
    if (Phead = = Pnode) return
        true;
 
    Path.push_back (phead);
 
    BOOL found = false;
    if (phead->m_pleft!= NULL)
        found = Getnodepath (Phead->m_pleft, Pnode, path);
    if (!found && phead->m_pright)
        found = Getnodepath (phead->m_pright, Pnode, path);
 
    if (!found)
        path.pop_back ();
 
    return found;
}


Since this path starts with the node. The lowest common parent node is the last common node in the path:

//Get the last common Node in Two lists:path1 and path2
/////////////////////////////////////////////////////////////////////////////////
treenode* Lastcommonnode
(
    const std::list<treenode*>& path1,
    const std::list<treenode*>& path2
)
{
    std::list<treenode*>::const_iterator Iterator1 = Path1.begin ();
    Std::list<treenode*>::const_iterator Iterator2 = Path2.begin ();
   
    treenode* pLast = NULL;
 
    while (Iterator1!= path1.end () && Iterator2!= path2.end ())
    {
        if (*iterator1 = = *iterator2)
            PLast = *iterator1;
 
        iterator1++;
        iterator2++;
    }
 
    return pLast;
}


With the previous two child functions, it is easy to find the lowest common parent node for two nodes. We first find two paths from the root node to two nodes, and then find the last common node of two paths. The code is as follows:

//Find the last parent of PNode1 and PNode2 in A and head phead
//////////////////////////////////////////////////////////////////////
treenode* lastcommonparent_2 (treenode* phead, treenode* pNode1, treenode* pNode2)
{
    if (phead = = NULL | | PNode1 = = NULL | | PNode2 = null) return
        null;
 
    Std::list<treenode*> path1;
    Getnodepath (Phead, PNode1, path1);
 
    Std::list<treenode*> path2;
    Getnodepath (Phead, PNode2, path2);
 
    Return Lastcommonnode (path1, path2);
}


The time complexity of this idea is O (n), the time efficiency is much better than the first method. But at the same time we should also note that this kind of thinking requires two linked lists to save the path, space efficiency is not the first method.

This article has been included in the "sword refers to offer--famous business interviewer" a typical programming problem, there are changes in the book of analysis to explain more detailed. Welcome attention.

Bo Master He Haitao to this blog article enjoy copyright. The network reprint please indicate the source http://zhedahht.blog.163.com/. Please contact the author to organize your publication.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.