Lowest Common Ancestor****

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

        _______3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4

For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

 

Analyse:

Trial 1: For the current node, if p and q are at different subtree, then return current node. If p and q are both at left subtree, then recursively judge the left subtree. If p and q are both at right subtree, then recursively judge the right subtree. 

To judge the rough position of p and q, we need a function which can determine whether the current root reaches to a target node.

For example, if we want to find the LCA of node 7 and node 8. We first find that node 7 and node 5 are connected, and node 8 and node 1 are connected. That is to say, node 7 and node 8 are at the left subtree and right subtree of the root respectively. Then we return node 3.

Runtime: TIME LIMIT EXCEEDED...

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
13         if(!root) return NULL;
14         if(reach(root->left, p) && reach(root->left, q)) 
15             return lowestCommonAncestor(root->left, p, q);
16         if(reach(root->right, p) && reach(root->right, q)) 
17             return lowestCommonAncestor(root->right, p, q);
18         return root;
19     }
20     bool reach(TreeNode* root, TreeNode* target){//find whether root reaches the target node
21         if(!root) return false;
22         if(root == target) return true;
23         return reach(root->left, target) || reach(root->right, target);
24     }
25 };
View Code

 

Trial 2: If the current node equals to one of the node, then we only need to find the location of another node. See from Solution

Runtime: 24ms.

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
13         if(!root) return NULL;
14         if(root == p || root == q) return root;
15         TreeNode* leftSub = lowestCommonAncestor(root->left, p, q);
16         TreeNode* rightSub = lowestCommonAncestor(root->right, p, q);
17         
18         if(leftSub && rightSub) return root;
19         return leftSub ? leftSub : rightSub;
20     }
21 };

 

posted @ 2015-08-03 00:05  amazingzoe  阅读(197)  评论(0编辑  收藏  举报