1. 程式人生 > 實用技巧 >微軟面試題: 236. 二叉樹的最近公共祖先 出現次數:3

微軟面試題: 236. 二叉樹的最近公共祖先 出現次數:3

題目描述:給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 
12 unordered_map<TreeNode*,int
> count_map; 13 public: 14 TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 15 { 16 //p、q 有一個是 根節點,根節點就是兩者的 最近公共祖先 17 if(root == p || root == q) return root; 18 //分別計算 左右子樹中 含有 p 、 q的數量 19 int left = serach_target(root->left,p,q); 20 int
right = serach_target(root->right,p,q); 21 //p 、q 在左右子樹 中一邊一個,根節點就是兩者的 最近公共祖先 22 if(left == 1 && right == 1) return root; 23 //p 、q 全在左子樹中,遞迴地在 左子樹中尋找 p q 公共祖先 24 else if(left == 2) 25 { 26 return lowestCommonAncestor(root->left,p,q); 27
} 28 //p 、q 全在右子樹中,遞迴地在 右子樹中尋找 p q 公共祖先 29 else if(right == 2) 30 { 31 return lowestCommonAncestor(root->right,p,q); 32 } 33 //上面已經把所有情況列舉過,這裡的僅僅return 僅為過編譯 34 return NULL; 35 } 36 //統計root 中統計 含有的 p 、q數量 返回可能為 0,1,2 37 int serach_target(TreeNode* root, TreeNode* p, TreeNode* q) 38 { 39 if(root == NULL) return 0; 40 // if(count_map.find(root)!= count_map.end()) return count_map[root]; 41 int ret = 0; 42 if(root == p || root == q) ret++; 43 int left = serach_target(root->left,p,q); 44 int right = serach_target(root->right,p,q); 45 //count_map[root] = ret + left +right; 46 return ret + left +right; 47 } 48 };

別人更簡潔的程式碼:

 1 class Solution {
 2 public:
 3     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
 4         if(root==NULL) return NULL;
 5         if(root==p||root==q) return root;           //在同一支,父子孫節點
 6 
 7         TreeNode*left=lowestCommonAncestor(root->left, p, q);
 8         TreeNode*right=lowestCommonAncestor(root->right, p, q);
 9 
10         if(left==NULL)  return right;
11         else if(right==NULL) return left;
12         else return root;    //root在p,q中間  (left!=NULL&&right!=NULL) 
13     }
14 };
15 //left==NULL&&right==NULL   本題說給定的兩個節點都存在,所以不需要考慮這種情況