一。后序遍历
1.如果本节点为空或者为c1/c2,则返回本节点
2.后序遍历
3.如果两个子树传的值都不为空,则返回本节点(说明找到了两个目标节点)
4.如果有一个节点为空,则另一个为空的可能是目标节点或者已经找到的公共祖先,此时则上传该值即可。
//
// main.cpp
// 二叉树中两个节点的最近公共节点
//
// Created by zjl on 16/9/17.
// Copyright © 2016年 zjl. All rights reserved.
//
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
};
TreeNode* create(vector<int>vec){
int num = vec.size();
TreeNode* root = new TreeNode(vec[0]);
queue<TreeNode*> q;
q.push(root);
int i = 1;
while(i <= num){
TreeNode* t = q.front();
q.pop();
if(vec[i] > 0){
t->left = new TreeNode(vec[i]);
q.push(t->left);
}
else
t->left = NULL;
i++;
if(i<= num){
if(vec[i] > 0){
t->right = new TreeNode(vec[i]);
q.push(t->right);
}
else
t->right = NULL;
i++;
}
}
return root;
}
TreeNode* solve(TreeNode* root, TreeNode* r1, TreeNode* r2){
if(root == NULL || root == r1 || root == r2)
return root;
TreeNode* left = solve(root->left, r1, r2);
TreeNode* right = solve(root->right, r1, r2);
if(left != NULL && right != NULL)
return root;
return left != NULL ? left : right;
}
int main(int argc, const char * argv[]) {
// insert code here...
vector<int>num={1,2,3};
TreeNode* root = create(num);
TreeNode* c1 = new TreeNode(2);
TreeNode* c2 = new TreeNode(3);
TreeNode* res = solve(root, root->left,root->right);
cout<< res->val <<endl;
return 0;
}
二、用数组存储信息,以便多次查询 时间复杂度O(N) 空间复杂度O(N ) 查找的时间复杂度为O(h) h为树的高度
过程:
1.为每个节点和其父节点建立映射
2.对目标节点1,对其的一条路径放到set中,然后对目标节点2在这集合中进行查找,如果没找到,就对节点2的父节点在这集合中找,直到找到为止
//
// main.cpp
// 二叉树中两个节点的最近公共节点2
//
// Created by zjl on 16/9/17.
// Copyright © 2016年 zjl. All rights reserved.
// 用数组记录信息
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
};
map<TreeNode*, TreeNode*>mp;
TreeNode* create(vector<int>vec){
int num = vec.size();
TreeNode* root = new TreeNode(vec[0]);
queue<TreeNode*> q;
q.push(root);
int i = 1;
while(i <= num){
TreeNode* t = q.front();
q.pop();
if(vec[i] > 0){
t->left = new TreeNode(vec[i]);
q.push(t->left);
}
else
t->left = NULL;
i++;
if(i<= num){
if(vec[i] > 0){
t->right = new TreeNode(vec[i]);
q.push(t->right);
}
else
t->right = NULL;
i++;
}
}
return root;
}
//set map value as <root, root's father>
void setmap(TreeNode* root){
if(root == NULL) return;
if(root->left != NULL)
mp.insert(pair<TreeNode*, TreeNode*>(root->left, root));
if(root->right != NULL)
mp.insert(pair<TreeNode*, TreeNode*>(root->right, root));
setmap(root->left);
setmap(root->right);
}
//把c1的一整条路径放入set中,然后c2就在当中找,若没找到,则上升到c2的父节点找
TreeNode* search(TreeNode* c1, TreeNode* c2){
set<TreeNode*>sets;
while(mp.find(c1) != mp.end()){
sets.insert(c1);
c1 = mp[c1];
}
while(sets.find(c2) == sets.end()){
c2 = mp[c2];
}
return c2;
}
TreeNode* solve(TreeNode* root, TreeNode* c1, TreeNode* c2){
if(root != NULL) mp.insert(pair<TreeNode*, TreeNode*>(root, NULL));
setmap(root); //先把每个节点找到其父节点
return search(c1, c2);
}
int main(int argc, const char * argv[]) {
// insert code here...
vector<int>num={1,2,3};
TreeNode* root = create(num);
TreeNode* res = solve(root, root->left,root->right);
cout<< res->val <<endl;
return 0;
}