LeetCode 235 BST的最近公共祖先

这个题目比一般二叉树的最近公共祖先更佳的具体化,因为左右遍历路径都可以提前确定。

由于BST TREE的特点

1.当p,q节点在root的不同子树上的时候,root就位根节点

2.p或者q就是root的时候,返回root

3.p,q同时在root的左子树或者右子树,那么就递归遍历左子树或者右子树

1 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
2         while( (root->val - p->val)*(root->val - q->val) >0){
3             root = p->val > root->val ? root->right : root->left;
4         }
5         return root;
6 }

这个是针对本题比较简单的方法,更一般的方法可见 二叉树的最近公共祖先 http://www.cnblogs.com/ackerzju/p/5015177.html 

 

solution2:

但是针对一般的二叉树也许我们还会有这样的解法:

针对上图:

先序遍历: 1 2 4 5 7 8 9 3 6

中序遍历: 4 2 7 5 9 8 1 3 6

p在val为4的位置,q在val为9的位置

那么找最近祖先就雷同中序先序构建二叉树的情况了,

1.根节点为p或者q,那么最近祖先就是根节点

2.如果pq分别在根节点的不同子树,那么最近祖先就是根节点

3.pq同时在左子树或者右子树,遍历左右子树

 1 //根据中序以及先序来查找最近公共祖先
 2     //中序中找到头节点,
 3     // 如果头节点与p相等,那么公共祖先就是p,返回p。 如果与q相等那么就返回q
 4     // 否则,如果p和q出现在中序头节点的两边,那么说明这个头节点就是最近公共祖先,返回头节点
 5     // 否则就说明pq在头节点的左子树或者是右子树,那么递归左子树或者递归右子树
 6     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q){
 7         vector<TreeNode*> preArr;
 8         vector<TreeNode*> inArr;
 9         preorder(root, preArr);
10         inorder(root, inArr);
11         TreeNode* parent;
12         getParent(p, q, preArr, 0, preArr.size()-1, inArr, 0, inArr.size()-1, parent);
13         return parent;
14     }
15     void inorder(TreeNode* root, vector<TreeNode*>& order){ //中序遍历
16         if(root==NULL) return;
17         inorder(root->left, order);
18         order.push_back(root);
19         inorder(root->right, order);
20     }
21     void preorder(TreeNode* root, vector<TreeNode*>& order){//先序遍历
22         if(root==NULL) return;
23         order.push_back(root);
24         preorder(root->left, order);
25         preorder(root->right, order);
26     }
27     void getParent(TreeNode* p, TreeNode* q,vector<TreeNode*> preArr,int preL,int preR, vector<TreeNode*> inArr, int inL, int inR, TreeNode* &parent){
28         if(preL > preR) return;
29         if(preArr[preL] == p) { parent = p; return;}
30         if(preArr[preL] == q) { parent = q; return;}
31         int x,y,k;
32         for(int i=inL; i<=inR; ++i){
33             if(inArr[i] == preArr[preL])
34                 k = i;
35             else if(inArr[i] == p){
36                 x = i;
37             }
38             else if(inArr[i] == q){
39                 y = i;
40             }
41         }
42         if((k-x) * (k-y) < 0){
43             parent = inArr[k];
44             return;
45         }
46         int num = k-inL;
47         if(x<k)
48             getParent(p, q, preArr, preL+1, preL+num, inArr, inL, k-1, parent);
49         else
50             getParent(p, q, preArr, preL+num+1, preR, inArr, k+1, inR, parent);
51     }

但是这种做法的空间复杂度,在leetcode上会溢出

 

posted @ 2015-12-03 12:59  Acker  阅读(353)  评论(0编辑  收藏  举报