【树】236. 二叉树的最近公共祖先

题目:

【树】236. 二叉树的最近公共祖先

 

 

解答:

(递归) O(n)

当我们用递归去做这个题时不要被题目误导,应该要明确一点:这个函数的功能有三个:给定两个节点 p和 q

(1)如果 p 和 q 都存在,则返回它们的公共祖先;

(2)如果只存在一个,则返回存在的一个;

(3)如果 p 和 q 都不存在,则返回NULL

本题说给定的两个节点都存在,那自然还是能用上面的函数来解决

具体思路:

(1) 如果当前结点 root等于NULL,则直接返回NULL;

(2) 如果 root 等于 p或者 q ,那这棵树一定返回 p或者 q;

(3) 然后递归左右子树,因为是递归,使用函数后可认为左右子树已经算出结果,用 left 和 right 表示;

(4) 此时若left为空,那最终结果只要看 right;若 right为空,那最终结果只要看 left;

(5) 如果 left 和 right 都非空,因为只给了 p 和 q 两个结点,都非空,说明一边一个,因此 root 是他们的最近公共祖先;

(6) 如果 left 和 right都为空,则返回空(其实已经包含在前面的情况中了);

时间复杂度是O(n):每个结点最多遍历一次或用主定理,空间复杂度是O(n):需要系统栈空间。

 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 public:
12     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
13     {
14         if(root == NULL)
15         {
16            return NULL;
17         }
18         if(root == p || root == q)
19         { 
20             return root;
21         }
22             
23         TreeNode* left =  lowestCommonAncestor(root->left, p, q);
24         TreeNode* right = lowestCommonAncestor(root->right, p, q);
25        
26         if(left == NULL)
27             return right;
28         if(right == NULL)
29             return left;      
30         if(left && right) // p和q在两侧
31             return root;
32         
33         return NULL; // 必须有返回值      
34     }
35 };

 

上一篇:LeetCode#236二叉树的最近公共祖先


下一篇:236. 二叉树的最近公共祖先(快手面试)