51
51
52
52
### 方法一:递归
53
53
54
- 根据“ ** 最近公共祖先 ** ”的定义,若 root 是 p, q 的最近公共祖先 ,则只可能为以下情况之一 :
54
+ 我们递归遍历二叉树 :
55
55
56
- - 如果 p 和 q 分别是 root 的左右节点,那么 root 就是我们要找的最近公共祖先;
57
- - 如果 p 和 q 都是 root 的左节点,那么返回 ` lowestCommonAncestor(root.left, p, q) ` ;
58
- - 如果 p 和 q 都是 root 的右节点,那么返回 ` lowestCommonAncestor(root.right, p, q) ` 。
56
+ 如果当前节点为空或者等于 $p$ 或者 $q$,则返回当前节点;
59
57
60
- ** 边界条件讨论 ** :
58
+ 否则,我们递归遍历左右子树,将返回的结果分别记为 $left$ 和 $right$。如果 $left$ 和 $right$ 都不为空,则说明 $p$ 和 $q$ 分别在左右子树中,因此当前节点即为最近公共祖先;如果 $left$ 和 $right$ 中只有一个不为空,返回不为空的那个。
61
59
62
- - 如果 root 为 null,则说明我们已经找到最底了,返回 null 表示没找到;
63
- - 如果 root 与 p 相等或者与 q 相等,则返回 root;
64
- - 如果左子树没找到,递归函数返回 null,证明 p 和 q 同在 root 的右侧,那么最终的公共祖先就是右子树找到的结点;
65
- - 如果右子树没找到,递归函数返回 null,证明 p 和 q 同在 root 的左侧,那么最终的公共祖先就是左子树找到的结点。
60
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树节点个数。
66
61
67
62
<!-- tabs:start -->
68
63
77
72
78
73
class Solution :
79
74
def lowestCommonAncestor (
80
- self , root : ' TreeNode' , p : ' TreeNode' , q : ' TreeNode'
81
- ) -> ' TreeNode' :
82
- if root is None or root == p or root == q :
75
+ self , root : " TreeNode" , p : " TreeNode" , q : " TreeNode"
76
+ ) -> " TreeNode" :
77
+ if root in ( None , p, q) :
83
78
return root
84
79
left = self .lowestCommonAncestor(root.left, p, q)
85
80
right = self .lowestCommonAncestor(root.right, p, q)
@@ -98,12 +93,15 @@ class Solution:
98
93
*/
99
94
class Solution {
100
95
public TreeNode lowestCommonAncestor (TreeNode root , TreeNode p , TreeNode q ) {
101
- if (root == null || root == p || root == q) return root;
102
- TreeNode left = lowestCommonAncestor(root. left, p, q);
103
- TreeNode right = lowestCommonAncestor(root. right, p, q);
104
- if (left == null ) return right;
105
- if (right == null ) return left;
106
- return root;
96
+ if (root == null || root == p || root == q) {
97
+ return root;
98
+ }
99
+ var left = lowestCommonAncestor(root. left, p, q);
100
+ var right = lowestCommonAncestor(root. right, p, q);
101
+ if (left != null && right != null ) {
102
+ return root;
103
+ }
104
+ return left == null ? right : left;
107
105
}
108
106
}
109
107
```
@@ -121,10 +119,14 @@ class Solution {
121
119
class Solution {
122
120
public:
123
121
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
124
- if (!root || root == p || root == q) return root;
125
- TreeNode* left = lowestCommonAncestor(root->left, p, q);
126
- TreeNode* right = lowestCommonAncestor(root->right, p, q);
127
- if (left && right) return root;
122
+ if (root == nullptr || root == p || root == q) {
123
+ return root;
124
+ }
125
+ auto left = lowestCommonAncestor(root->left, p, q);
126
+ auto right = lowestCommonAncestor(root->right, p, q);
127
+ if (left && right) {
128
+ return root;
129
+ }
128
130
return left ? left : right;
129
131
}
130
132
};
@@ -145,13 +147,13 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
145
147
}
146
148
left := lowestCommonAncestor(root.Left, p, q)
147
149
right := lowestCommonAncestor(root.Right, p, q)
148
- if left = = nil {
149
- return right
150
+ if left != nil && right ! = nil {
151
+ return root
150
152
}
151
- if right = = nil {
153
+ if left ! = nil {
152
154
return left
153
155
}
154
- return root
156
+ return right
155
157
}
156
158
```
157
159
@@ -175,21 +177,12 @@ function lowestCommonAncestor(
175
177
p : TreeNode | null ,
176
178
q : TreeNode | null ,
177
179
): TreeNode | null {
178
- const find = (root : TreeNode | null ) => {
179
- if (root == null || root == p || root == q ) {
180
- return root ;
181
- }
182
- const left = find (root .left );
183
- const right = find (root .right );
184
- if (left != null && right != null ) {
185
- return root ;
186
- }
187
- if (left != null ) {
188
- return left ;
189
- }
190
- return right ;
191
- };
192
- return find (root );
180
+ if (! root || root === p || root === q ) {
181
+ return root ;
182
+ }
183
+ const left = lowestCommonAncestor (root .left , p , q );
184
+ const right = lowestCommonAncestor (root .right , p , q );
185
+ return left && right ? root : left || right ;
193
186
}
194
187
```
195
188
@@ -215,31 +208,31 @@ function lowestCommonAncestor(
215
208
use std :: rc :: Rc ;
216
209
use std :: cell :: RefCell ;
217
210
impl Solution {
218
- fn find (
219
- root : & Option <Rc <RefCell <TreeNode >>>,
220
- p : & Option <Rc <RefCell <TreeNode >>>,
221
- q : & Option <Rc <RefCell <TreeNode >>>
222
- ) -> Option <Rc <RefCell <TreeNode >>> {
223
- if root . is_none () || root == p || root == q {
224
- return root . clone ();
225
- }
226
- let node = root . as_ref (). unwrap (). borrow ();
227
- let left = Self :: find (& node . left, p , q );
228
- let right = Self :: find (& node . right, p , q );
229
- match (left . is_some (), right . is_some ()) {
230
- (true , false ) => left ,
231
- (false , true ) => right ,
232
- (false , false ) => None ,
233
- (true , true ) => root . clone (),
234
- }
235
- }
236
-
237
211
pub fn lowest_common_ancestor (
238
212
root : Option <Rc <RefCell <TreeNode >>>,
239
213
p : Option <Rc <RefCell <TreeNode >>>,
240
214
q : Option <Rc <RefCell <TreeNode >>>
241
215
) -> Option <Rc <RefCell <TreeNode >>> {
242
- Self :: find (& root , & p , & q )
216
+ if root . is_none () || root == p || root == q {
217
+ return root ;
218
+ }
219
+ let left = Self :: lowest_common_ancestor (
220
+ root . as_ref (). unwrap (). borrow (). left. clone (),
221
+ p . clone (),
222
+ q . clone ()
223
+ );
224
+ let right = Self :: lowest_common_ancestor (
225
+ root . as_ref (). unwrap (). borrow (). right. clone (),
226
+ p . clone (),
227
+ q . clone ()
228
+ );
229
+ if left . is_some () && right . is_some () {
230
+ return root ;
231
+ }
232
+ if left . is_none () {
233
+ return right ;
234
+ }
235
+ return left ;
243
236
}
244
237
}
245
238
```
@@ -259,12 +252,12 @@ impl Solution {
259
252
* @return {TreeNode}
260
253
*/
261
254
var lowestCommonAncestor = function (root , p , q ) {
262
- if (! root || root == p || root == q) return root;
255
+ if (! root || root === p || root === q) {
256
+ return root;
257
+ }
263
258
const left = lowestCommonAncestor (root .left , p, q);
264
259
const right = lowestCommonAncestor (root .right , p, q);
265
- if (! left) return right;
266
- if (! right) return left;
267
- return root;
260
+ return left && right ? root : left || right;
268
261
};
269
262
```
270
263
0 commit comments