29
29
30
30
## 解法
31
31
32
- ### 方法一
32
+ ### 方法一:递归
33
+
34
+ 我们首先判断 $t_2$ 是否为空,如果为空,那么 $t_2$ 一定是 $t_1$ 的子树,返回 ` true ` 。
35
+
36
+ 否则,判断 $t_1$ 是否为空,如果为空,那么 $t_2$ 一定不是 $t_1$ 的子树,返回 ` false ` 。
37
+
38
+ 接着,我们判断 $t_1$ 和 $t_2$ 是否相等,如果相等,那么 $t_2$ 是 $t_1$ 的子树,返回 ` true ` 。否则,我们递归判断 $t_1$ 的左子树和 $t_2$ 是否相等,以及 $t_1$ 的右子树和 $t_2$ 是否相等,只要有一个为 ` true ` ,那么 $t_2$ 就是 $t_1$ 的子树,返回 ` true ` 。
39
+
40
+ 时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为 $t_1$ 的节点数。
33
41
34
42
<!-- tabs:start -->
35
43
@@ -46,14 +54,18 @@ class Solution:
46
54
def checkSubTree (self , t1 : TreeNode, t2 : TreeNode) -> bool :
47
55
def dfs (t1 , t2 ):
48
56
if t2 is None :
49
- return True
50
- if t1 is None :
57
+ return t1 is None
58
+ if t1 is None or t1.val != t2.val :
51
59
return False
52
- if t1.val == t2.val:
53
- return dfs(t1.left, t2.left) and dfs(t1.right, t2.right)
54
- return dfs(t1.left, t2) or dfs(t1.right, t2)
60
+ return dfs(t1.left, t2.left) and dfs(t1.right, t2.right)
55
61
56
- return dfs(t1, t2)
62
+ if t2 is None :
63
+ return True
64
+ if t1 is None :
65
+ return False
66
+ if dfs(t1, t2):
67
+ return True
68
+ return self .checkSubTree(t1.left, t2) or self .checkSubTree(t1.right, t2)
57
69
```
58
70
59
71
``` java
@@ -74,11 +86,21 @@ class Solution {
74
86
if (t1 == null ) {
75
87
return false ;
76
88
}
77
- if (t1 . val == t2 . val ) {
78
- return checkSubTree(t1 . left, t2 . left) && checkSubTree(t1 . right, t2 . right) ;
89
+ if (dfs(t1, t2) ) {
90
+ return true ;
79
91
}
80
92
return checkSubTree(t1. left, t2) || checkSubTree(t1. right, t2);
81
93
}
94
+
95
+ private boolean dfs (TreeNode t1 , TreeNode t2 ) {
96
+ if (t2 == null ) {
97
+ return t1 == null ;
98
+ }
99
+ if (t1 == null || t1. val != t2. val) {
100
+ return false ;
101
+ }
102
+ return dfs(t1. left, t2. left) && dfs(t1. right, t2. right);
103
+ }
82
104
}
83
105
```
84
106
@@ -95,11 +117,27 @@ class Solution {
95
117
class Solution {
96
118
public:
97
119
bool checkSubTree(TreeNode* t1, TreeNode* t2) {
98
- if (!t2) return 1;
99
- if (!t1) return 0;
100
- if (t1->val == t2->val) return checkSubTree(t1->left, t2->left) && checkSubTree(t1->right, t2->right);
120
+ if (!t2) {
121
+ return true;
122
+ }
123
+ if (!t1) {
124
+ return false;
125
+ }
126
+ if (dfs(t1, t2)) {
127
+ return true;
128
+ }
101
129
return checkSubTree(t1->left, t2) || checkSubTree(t1->right, t2);
102
130
}
131
+
132
+ bool dfs(TreeNode* t1, TreeNode* t2) {
133
+ if (!t2) {
134
+ return !t1;
135
+ }
136
+ if (!t1 || t1->val != t2->val) {
137
+ return false;
138
+ }
139
+ return dfs(t1->left, t2->left) && dfs(t1->right, t2->right);
140
+ }
103
141
};
104
142
```
105
143
@@ -113,14 +151,24 @@ public:
113
151
* }
114
152
*/
115
153
func checkSubTree (t1 *TreeNode , t2 *TreeNode ) bool {
154
+ var dfs func (t1, t2 *TreeNode) bool
155
+ dfs = func (t1, t2 *TreeNode) bool {
156
+ if t2 == nil {
157
+ return t1 == nil
158
+ }
159
+ if t1 == nil || t1.Val != t2.Val {
160
+ return false
161
+ }
162
+ return dfs (t1.Left , t2.Left ) && dfs (t1.Right , t2.Right )
163
+ }
116
164
if t2 == nil {
117
165
return true
118
166
}
119
167
if t1 == nil {
120
168
return false
121
169
}
122
- if t1.Val == t2.Val {
123
- return checkSubTree(t1.Left, t2.Left) && checkSubTree(t1.Right, t2.Right)
170
+ if dfs (t1, t2) {
171
+ return true
124
172
}
125
173
return checkSubTree (t1.Left , t2) || checkSubTree (t1.Right , t2)
126
174
}
@@ -142,14 +190,23 @@ func checkSubTree(t1 *TreeNode, t2 *TreeNode) bool {
142
190
*/
143
191
144
192
function checkSubTree(t1 : TreeNode | null , t2 : TreeNode | null ): boolean {
145
- if (t1 == null && t2 == null ) {
193
+ const dfs = (t1 : TreeNode | null , t2 : TreeNode | null ): boolean => {
194
+ if (! t2 ) {
195
+ return ! t1 ;
196
+ }
197
+ if (! t1 || t1 .val !== t2 .val ) {
198
+ return false ;
199
+ }
200
+ return dfs (t1 .left , t2 .left ) && dfs (t1 .right , t2 .right );
201
+ };
202
+ if (! t2 ) {
146
203
return true ;
147
204
}
148
- if (t1 == null || t2 == null ) {
205
+ if (! t1 ) {
149
206
return false ;
150
207
}
151
- if (t1 . val === t2 . val ) {
152
- return checkSubTree ( t1 . left , t2 . left ) && checkSubTree ( t1 . right , t2 . right ) ;
208
+ if (dfs ( t1 , t2 ) ) {
209
+ return true ;
153
210
}
154
211
return checkSubTree (t1 .left , t2 ) || checkSubTree (t1 .right , t2 );
155
212
}
@@ -178,25 +235,36 @@ use std::rc::Rc;
178
235
use std :: cell :: RefCell ;
179
236
impl Solution {
180
237
fn dfs (t1 : & Option <Rc <RefCell <TreeNode >>>, t2 : & Option <Rc <RefCell <TreeNode >>>) -> bool {
181
- if t1 . is_none () && t2 . is_none () {
182
- return true ;
238
+ match (t1 , t2 ) {
239
+ (Some (node1 ), Some (node2 )) => {
240
+ let n1 = node1 . borrow ();
241
+ let n2 = node2 . borrow ();
242
+ n1 . val == n2 . val &&
243
+ Solution :: dfs (& n1 . left, & n2 . left) &&
244
+ Solution :: dfs (& n1 . right, & n2 . right)
245
+ }
246
+ (None , Some (_ )) => false ,
247
+ (Some (_ ), None ) => false ,
248
+ _ => true , // Both are None
183
249
}
184
- if t1 . is_none () || t2 . is_none () {
185
- return false ;
186
- }
187
- let r1 = t1 . as_ref (). unwrap (). borrow ();
188
- let r2 = t2 . as_ref (). unwrap (). borrow ();
189
- if r1 . val == r2 . val {
190
- return Self :: dfs (& r1 . left, & r2 . left) && Self :: dfs (& r1 . right, & r2 . right);
191
- }
192
- Self :: dfs (& r1 . left, t2 ) || Self :: dfs (& r1 . right, t2 )
193
250
}
194
251
195
252
pub fn check_sub_tree (
196
253
t1 : Option <Rc <RefCell <TreeNode >>>,
197
254
t2 : Option <Rc <RefCell <TreeNode >>>
198
255
) -> bool {
199
- Self :: dfs (& t1 , & t2 )
256
+ match (t1 , t2 ) {
257
+ (Some (node1 ), Some (node2 )) => {
258
+ let n1 = node1 . borrow ();
259
+ let n2 = node2 . borrow ();
260
+ Solution :: dfs (& Some (Rc :: clone (& node1 )), & Some (Rc :: clone (& node2 ))) ||
261
+ Solution :: check_sub_tree (n1 . left. clone (), Some (Rc :: clone (& node2 ))) ||
262
+ Solution :: check_sub_tree (n1 . right. clone (), Some (Rc :: clone (& node2 )))
263
+ }
264
+ (Some (_ ), None ) => true ,
265
+ (None , Some (_ )) => false ,
266
+ _ => true , // Both are None or t1 is None
267
+ }
200
268
}
201
269
}
202
270
```
0 commit comments