Skip to content

Commit 210021b

Browse files
authored
fix: update solutions to lcci problem: No.04.10 (doocs#2664)
No.04.10.Check SubTree
1 parent 426f993 commit 210021b

File tree

13 files changed

+320
-119
lines changed

13 files changed

+320
-119
lines changed

lcci/04.10.Check SubTree/README.md

+98-30
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,15 @@
2929

3030
## 解法
3131

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$ 的节点数。
3341

3442
<!-- tabs:start -->
3543

@@ -46,14 +54,18 @@ class Solution:
4654
def checkSubTree(self, t1: TreeNode, t2: TreeNode) -> bool:
4755
def dfs(t1, t2):
4856
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:
5159
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)
5561

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)
5769
```
5870

5971
```java
@@ -74,11 +86,21 @@ class Solution {
7486
if (t1 == null) {
7587
return false;
7688
}
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;
7991
}
8092
return checkSubTree(t1.left, t2) || checkSubTree(t1.right, t2);
8193
}
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+
}
82104
}
83105
```
84106

@@ -95,11 +117,27 @@ class Solution {
95117
class Solution {
96118
public:
97119
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+
}
101129
return checkSubTree(t1->left, t2) || checkSubTree(t1->right, t2);
102130
}
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+
}
103141
};
104142
```
105143

@@ -113,14 +151,24 @@ public:
113151
* }
114152
*/
115153
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+
}
116164
if t2 == nil {
117165
return true
118166
}
119167
if t1 == nil {
120168
return false
121169
}
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
124172
}
125173
return checkSubTree(t1.Left, t2) || checkSubTree(t1.Right, t2)
126174
}
@@ -142,14 +190,23 @@ func checkSubTree(t1 *TreeNode, t2 *TreeNode) bool {
142190
*/
143191

144192
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) {
146203
return true;
147204
}
148-
if (t1 == null || t2 == null) {
205+
if (!t1) {
149206
return false;
150207
}
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;
153210
}
154211
return checkSubTree(t1.left, t2) || checkSubTree(t1.right, t2);
155212
}
@@ -178,25 +235,36 @@ use std::rc::Rc;
178235
use std::cell::RefCell;
179236
impl Solution {
180237
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
183249
}
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)
193250
}
194251

195252
pub fn check_sub_tree(
196253
t1: Option<Rc<RefCell<TreeNode>>>,
197254
t2: Option<Rc<RefCell<TreeNode>>>
198255
) -> 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+
}
200268
}
201269
}
202270
```

0 commit comments

Comments
 (0)