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上会溢出