61
61
62
62
<!-- solution:start -->
63
63
64
- ### 方法一
64
+ ### 方法一:DFS
65
+
66
+ 我们定义一个辅助函数 $\textit{same}(p, q)$,用于判断以 $p$ 为根节点的树和以 $q$ 为根节点的树是否相等。如果两棵树的根节点的值相等,并且它们的左子树和右子树也分别相等,那么这两棵树是相等的。
67
+
68
+ 在 $\textit{isSubtree}(\textit{root}, \textit{subRoot})$ 函数中,我们首先判断 $\textit{root}$ 是否为空,如果为空,则返回 $\text{false}$。否则,我们判断 $\textit{root}$ 和 $\textit{subRoot}$ 是否相等,如果相等,则返回 $\text{true}$。否则,我们递归地判断 $\textit{root}$ 的左子树和右子树是否包含 $\textit{subRoot}$。
69
+
70
+ 时间复杂度 $O(n \times m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是树 $root$ 和树 $subRoot$ 的节点个数。
65
71
66
72
<!-- tabs:start -->
67
73
@@ -75,22 +81,16 @@ tags:
75
81
# self.left = left
76
82
# self.right = right
77
83
class Solution :
78
- def isSubtree (self , root : TreeNode, subRoot : TreeNode) -> bool :
79
- def dfs (root1 , root2 ):
80
- if root1 is None and root2 is None :
81
- return True
82
- if root1 is None or root2 is None :
83
- return False
84
- return (
85
- root1.val == root2.val
86
- and dfs(root1.left, root2.left)
87
- and dfs(root1.right, root2.right)
88
- )
84
+ def isSubtree (self , root : Optional[TreeNode], subRoot : Optional[TreeNode]) -> bool :
85
+ def same (p : Optional[TreeNode], q : Optional[TreeNode]) -> bool :
86
+ if p is None or q is None :
87
+ return p is q
88
+ return p.val == q.val and same(p.left, q.left) and same(p.right, q.right)
89
89
90
90
if root is None :
91
91
return False
92
92
return (
93
- dfs (root, subRoot)
93
+ same (root, subRoot)
94
94
or self .isSubtree(root.left, subRoot)
95
95
or self .isSubtree(root.right, subRoot)
96
96
)
@@ -119,19 +119,15 @@ class Solution {
119
119
if (root == null ) {
120
120
return false ;
121
121
}
122
- return dfs (root, subRoot) || isSubtree(root. left, subRoot)
122
+ return same (root, subRoot) || isSubtree(root. left, subRoot)
123
123
|| isSubtree(root. right, subRoot);
124
124
}
125
125
126
- private boolean dfs (TreeNode root1 , TreeNode root2 ) {
127
- if (root1 == null && root2 == null ) {
128
- return true ;
129
- }
130
- if (root1 == null || root2 == null ) {
131
- return false ;
126
+ private boolean same (TreeNode p , TreeNode q ) {
127
+ if (p == null || q == null ) {
128
+ return p == q;
132
129
}
133
- return root1. val == root2. val && dfs(root1. left, root2. left)
134
- && dfs(root1. right, root2. right);
130
+ return p. val == q. val && same(p. left, q. left) && same(p. right, q. right);
135
131
}
136
132
}
137
133
```
@@ -153,14 +149,17 @@ class Solution {
153
149
class Solution {
154
150
public:
155
151
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
156
- if (!root) return 0;
157
- return dfs(root, subRoot) || isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
152
+ if (!root) {
153
+ return false;
154
+ }
155
+ return same(root, subRoot) || isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
158
156
}
159
157
160
- bool dfs(TreeNode* root1, TreeNode* root2) {
161
- if (!root1 && !root2) return 1;
162
- if (!root1 || !root2) return 0;
163
- return root1->val == root2->val && dfs(root1->left, root2->left) && dfs(root1->right, root2->right);
158
+ bool same(TreeNode* p, TreeNode* q) {
159
+ if (!p || !q) {
160
+ return p == q;
161
+ }
162
+ return p->val == q->val && same(p->left, q->left) && same(p->right, q->right);
164
163
}
165
164
};
166
165
```
@@ -177,20 +176,17 @@ public:
177
176
* }
178
177
*/
179
178
func isSubtree (root *TreeNode , subRoot *TreeNode ) bool {
179
+ var same func (p, q *TreeNode) bool
180
+ same = func (p, q *TreeNode) bool {
181
+ if p == nil || q == nil {
182
+ return p == q
183
+ }
184
+ return p.Val == q.Val && same (p.Left , q.Left ) && same (p.Right , q.Right )
185
+ }
180
186
if root == nil {
181
187
return false
182
188
}
183
- var dfs func (root1, root2 *TreeNode) bool
184
- dfs = func (root1, root2 *TreeNode) bool {
185
- if root1 == nil && root2 == nil {
186
- return true
187
- }
188
- if root1 == nil || root2 == nil {
189
- return false
190
- }
191
- return root1.Val == root2.Val && dfs (root1.Left , root2.Left ) && dfs (root1.Right , root2.Right )
192
- }
193
- return dfs (root, subRoot) || isSubtree (root.Left , subRoot) || isSubtree (root.Right , subRoot)
189
+ return same (root, subRoot) || isSubtree (root.Left , subRoot) || isSubtree (root.Right , subRoot)
194
190
}
195
191
```
196
192
@@ -210,22 +206,17 @@ func isSubtree(root *TreeNode, subRoot *TreeNode) bool {
210
206
* }
211
207
* }
212
208
*/
213
-
214
- const dfs = (root : TreeNode | null , subRoot : TreeNode | null ) => {
215
- if (root == null && subRoot == null ) {
216
- return true ;
217
- }
218
- if (root == null || subRoot == null || root .val !== subRoot .val ) {
219
- return false ;
220
- }
221
- return dfs (root .left , subRoot .left ) && dfs (root .right , subRoot .right );
222
- };
223
-
224
209
function isSubtree(root : TreeNode | null , subRoot : TreeNode | null ): boolean {
225
- if (root == null ) {
210
+ const same = (p : TreeNode | null , q : TreeNode | null ): boolean => {
211
+ if (! p || ! q ) {
212
+ return p === q ;
213
+ }
214
+ return p .val === q .val && same (p .left , q .left ) && same (p .right , q .right );
215
+ };
216
+ if (! root ) {
226
217
return false ;
227
218
}
228
- return dfs (root , subRoot ) || isSubtree (root .left , subRoot ) || isSubtree (root .right , subRoot );
219
+ return same (root , subRoot ) || isSubtree (root .left , subRoot ) || isSubtree (root .right , subRoot );
229
220
}
230
221
```
231
222
@@ -252,38 +243,36 @@ function isSubtree(root: TreeNode | null, subRoot: TreeNode | null): boolean {
252
243
// }
253
244
use std :: cell :: RefCell ;
254
245
use std :: rc :: Rc ;
255
- impl Solution {
256
- fn dfs (root : & Option <Rc <RefCell <TreeNode >>>, sub_root : & Option <Rc <RefCell <TreeNode >>>) -> bool {
257
- if root . is_none () && sub_root . is_none () {
258
- return true ;
259
- }
260
- if root . is_none () || sub_root . is_none () {
261
- return false ;
262
- }
263
- let root = root . as_ref (). unwrap (). borrow ();
264
- let sub_root = sub_root . as_ref (). unwrap (). borrow ();
265
- root . val == sub_root . val
266
- && Self :: dfs (& root . left, & sub_root . left)
267
- && Self :: dfs (& root . right, & sub_root . right)
268
- }
269
246
270
- fn help (
271
- root : & Option <Rc <RefCell <TreeNode >>>,
272
- sub_root : & Option <Rc <RefCell <TreeNode >>>,
247
+ impl Solution {
248
+ pub fn is_subtree (
249
+ root : Option <Rc <RefCell <TreeNode >>>,
250
+ sub_root : Option <Rc <RefCell <TreeNode >>>,
273
251
) -> bool {
274
252
if root . is_none () {
275
253
return false ;
276
254
}
277
- Self :: dfs (root , sub_root )
278
- || Self :: help (& root . as_ref (). unwrap (). borrow (). left, sub_root )
279
- || Self :: help (& root . as_ref (). unwrap (). borrow (). right, sub_root )
255
+ Self :: same (& root , & sub_root )
256
+ || Self :: is_subtree (
257
+ root . as_ref (). unwrap (). borrow (). left. clone (),
258
+ sub_root . clone (),
259
+ )
260
+ || Self :: is_subtree (
261
+ root . as_ref (). unwrap (). borrow (). right. clone (),
262
+ sub_root . clone (),
263
+ )
280
264
}
281
265
282
- pub fn is_subtree (
283
- root : Option <Rc <RefCell <TreeNode >>>,
284
- sub_root : Option <Rc <RefCell <TreeNode >>>,
285
- ) -> bool {
286
- Self :: help (& root , & sub_root )
266
+ fn same (p : & Option <Rc <RefCell <TreeNode >>>, q : & Option <Rc <RefCell <TreeNode >>>) -> bool {
267
+ match (p , q ) {
268
+ (None , None ) => true ,
269
+ (Some (p ), Some (q )) => {
270
+ let p = p . borrow ();
271
+ let q = q . borrow ();
272
+ p . val == q . val && Self :: same (& p . left, & q . left) && Self :: same (& p . right, & q . right)
273
+ }
274
+ _ => false ,
275
+ }
287
276
}
288
277
}
289
278
```
@@ -305,19 +294,16 @@ impl Solution {
305
294
* @return {boolean}
306
295
*/
307
296
var isSubtree = function (root , subRoot ) {
308
- if (! root) return false ;
309
- let dfs = function (root1 , root2 ) {
310
- if (! root1 && ! root2) {
311
- return true ;
297
+ const same = (p , q ) => {
298
+ if (! p || ! q) {
299
+ return p === q;
312
300
}
313
- if (! root1 || ! root2) {
314
- return false ;
315
- }
316
- return (
317
- root1 .val == root2 .val && dfs (root1 .left , root2 .left ) && dfs (root1 .right , root2 .right )
318
- );
301
+ return p .val === q .val && same (p .left , q .left ) && same (p .right , q .right );
319
302
};
320
- return dfs (root, subRoot) || isSubtree (root .left , subRoot) || isSubtree (root .right , subRoot);
303
+ if (! root) {
304
+ return false ;
305
+ }
306
+ return same (root, subRoot) || isSubtree (root .left , subRoot) || isSubtree (root .right , subRoot);
321
307
};
322
308
```
323
309
0 commit comments