Q: Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree. Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.
A:不允许额外的空间开销,那么就需要从根开始往下寻找。
因为根节点肯定是其共同的祖先,然后不断往下找,直到找到最后一个两个节点的共同祖先。
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 100;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode *parent;
TreeNode () {}
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
//初始化数据
TreeNode *dfs(vector<int> &num, int start, int end) {
if (start == end) {
return NULL;
}
int mid = start + (end-start)/2;
TreeNode *root = new TreeNode(num[mid]);
root->left = dfs(num, start, mid);
root->right = dfs(num, mid+1, end);
return root;
}
TreeNode *sortedArrayToBST(vector<int> &num) {
const int n = num.size();
if (n == 0) {
return NULL;
}
return dfs(num,0,n);
}
bool isAncestor(TreeNode *root, TreeNode *dst) {
if (!root) {
return false;
}
if (root == dst) {
return true;
}
return isAncestor(root->left, dst) || isAncestor(root->right, dst);
}
TreeNode* commonAncestorHelper(TreeNode *root, TreeNode *one, TreeNode *two) {
if (!root) {
return NULL;
}
if (root == one || root == two) {
return root;
}
bool is_one_on_left = isAncestor(root->left, one);
bool is_two_on_left = isAncestor(root->left, two);
if (is_one_on_left != is_two_on_left) {
return root;
}
TreeNode *child = is_one_on_left?root->left:root->right;
return commonAncestorHelper(child, one, two);
}
TreeNode* commenAncestor(TreeNode *root, TreeNode *one, TreeNode *two) {
if (!isAncestor(root, one) || !isAncestor(root, two)) {
return NULL;
}
return commonAncestorHelper(root, one, two);
}
TreeNode* search(TreeNode* head, int x){
if(head == NULL) return NULL;
else if(x == head->val) return head;
else if(x <= head->val) search(head->left, x);
else search(head->right, x);
}
int main(){
vector<int> a;
for (int i = 1; i < 10; i++) {
a.push_back(i);
}
TreeNode *head = sortedArrayToBST(a);
TreeNode *n1 = search(head, 2);
TreeNode *n2 = search(head, 4);
cout<<n1->val<<" "<<n2->val<<endl;
TreeNode *ans = commenAncestor(head, n1, n2);
cout<<ans->val<<endl;
return 0;
}