/
lowest_common_ancestor.cpp
121 lines (115 loc) · 3.89 KB
/
lowest_common_ancestor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
* 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.
*
*
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
// This method is pretty simple but pretty slow!!!!
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root||!p||!q) return root;
if(root==p||root==q) return root;
if(dfs(root->left,p)){
if(dfs(root->left,q)) return lowestCommonAncestor(root->left,p,q);
else return root;
}else{
if(dfs(root->right,q)) return lowestCommonAncestor(root->right,p,q);
else return root;
}
}
bool dfs(TreeNode* root,TreeNode* target){
if(!root||!target) return false;
if(root==target) return true;
return dfs(root->left,target)||dfs(root->right,target);
}
};
/* Method2*/
/**
* 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) {
if(!root||root==p||root==q) return root;
TreeNode* left = lowestCommonAncestor(root->left,p,q);
TreeNode* right = lowestCommonAncestor(root->right,p,q);
if(left&&right) return root;
else return left?left:right;
}
};
/*Method3 iterative way,postorder-traversal included*/
/**
* 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) {
if(!root||!p||!q) return root;
std::stack<TreeNode*> p_stack,q_stack;
getPath(p_stack,root,p);
getPath(q_stack,root,q);
//printf("%d%d",p_stack.top()->val,q_stack.top()->val);
//printf("%d%d",p_stack.size(),q_stack.size());
while(p_stack.size()>q_stack.size()) p_stack.pop();
while(p_stack.size()<q_stack.size()) q_stack.pop();
while(p_stack.top()!=q_stack.top()){
p_stack.pop();
q_stack.pop();
}
return p_stack.top();
}
void getPath(std::stack<TreeNode*>& path,TreeNode* root, TreeNode* target){
TreeNode* prev = nullptr;
//actually postorder traversal//since I cannot just pop it out need to go back to parent the second time
while(!path.empty() || root){
if(root==target){
path.push(root);
return;
}
if(root){
path.push(root);
root = root->left;
}else if((path.top()->right)==prev){
prev = path.top();
path.pop();
}else{
root = path.top();
prev = root;
root = root->right;
prev = nullptr;
}
}
}
};