法一
参考文章:
二叉树中的最低公共祖先 | GeeksforGeeks --- Lowest Common Ancestor in a Binary Tree | GeeksforGeeks
法一
用两个独立的数组储存根节点到节点的路径,然后从0开始遍历。LCA是这两个数组最后匹配的元素。
// C++ program to find LCA using Arrays to Store
// Paths of Nodes from Root
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node(int x) {
data = x;
left = nullptr;
right = nullptr;
}
};
// Function to find path from root to given node.
bool findPath(Node* root, vector<Node*>& path, int k) {
// base case
if (root == nullptr)
return false;
// Store current node value in the path.
path.push_back(root);
// If node value is equal to k, or
// if node exist in left subtree or
// if node exist in right subtree return true
if (root->data == k ||
findPath(root->left, path, k) ||
findPath(root->right, path, k))
return true;
// else remove root from path and return false
path.pop_back();
return false;
}
// Returns LCA of two nodes.
Node* lca(Node* root, int n1, int n2) {
// to store paths to n1 and n2 from the root
vector<Node*> path1, path2;
// Find paths from root to n1 and
// root to n2. If either
// n1 or n2 is not present, return nullptr
if (!findPath(root, path1, n1) ||
!findPath(root, path2, n2))
return nullptr;
// Compare the paths to get the first
// different value
int i;
for (i = 0; i < path1.size()
&& i < path2.size(); i++) {
if (path1[i] != path2[i])
return path1[i-1];
}
// if both the datas are same, return last node
return path1[i-1];
}
int main() {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
Node* ans = lca(root, 4, 5);
if(ans == nullptr)
cout<<"No common ancestor found";
else
cout<< ans->data;
return 0;
}
法二
The idea is to traverse the tree starting from the root. If any of the given keys* *(n1 and n2) matches* with the root, then the root is LCA (assuming that both keys are present). If the root *doesn’t* *match* with any of the keys, we *recur* for the *left* and *right* subtree. The node which has *one key* present in its *left* subtree and the *other key* present in the *right* subtree is the LCA, else if, both keys lie in the *left* subtree, then the *left* *subtree* has LCA, else the *LCA* lies in the *right* subtree.
// C++ program to find LCA using Single traversal
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
Node *left, *right;
int data;
Node(int k) {
data = k;
left = nullptr;
right = nullptr;
}
};
// Function to find LCA of two keys.
Node* lca(Node* root, int n1, int n2) {
if (!root)
return nullptr;
// If either key matches with root data, return root
if (root->data == n1 || root->data == n2)
return root;
// Look for datas in left and right subtrees
Node* leftLca = lca(root->left, n1, n2);
Node* rightLca = lca(root->right, n1, n2);
// If both of the above calls return Non-NULL, then one
// data is present in one subtree and the other is present
// in the other, so this node is the LCA
if (leftLca && rightLca)
return root;
// Otherwise check if left subtree or right subtree is
// LCA
return leftLca ? leftLca : rightLca;
}
int main() {
// construct the binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
Node* ans = lca(root, 4, 5);
if(ans == nullptr){
cout<<"No common ancestor found";
}
else{
cout<<ans->data;
}
return 0;
}
上述方法依赖于两个key都必须存在树中,而实际情况不同。需要寻找是否在树中。