微軟面試題: 236. 二叉樹的最近公共祖先 出現次數:3
阿新 • • 發佈:2020-11-14
題目描述:給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。
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 intright = 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 本題說給定的兩個節點都存在,所以不需要考慮這種情況