Skip to content

Commit 7dee275

Browse files
committed
Create 100.same-tree.md
1 parent 91ee456 commit 7dee275

File tree

1 file changed

+230
-0
lines changed

1 file changed

+230
-0
lines changed

problems/100.same-tree.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
## 题目地址(100. 相同的树)
2+
3+
https://leetcode-cn.com/problems/same-tree/
4+
5+
## 题目描述
6+
7+
```
8+
给定两个二叉树,编写一个函数来检验它们是否相同。
9+
10+
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
11+
12+
示例 1:
13+
14+
输入: 1 1
15+
/ \ / \
16+
2 3 2 3
17+
18+
[1,2,3], [1,2,3]
19+
20+
输出: true
21+
示例 2:
22+
23+
输入: 1 1
24+
/ \
25+
2 2
26+
27+
[1,2], [1,null,2]
28+
29+
输出: false
30+
示例 3:
31+
32+
输入: 1 1
33+
/ \ / \
34+
2 1 1 2
35+
36+
[1,2,1], [1,1,2]
37+
38+
输出: false
39+
```
40+
41+
## 前置知识
42+
43+
- 递归
44+
- 层序遍历
45+
- 前中序确定一棵树
46+
47+
## 递归
48+
49+
### 思路
50+
51+
最简单的想法是递归,这里先介绍下递归三要素
52+
53+
- 递归出口,问题最简单的情况
54+
- 递归调用总是去尝试解决更小的问题,这样问题才会被收敛到最简单的情况
55+
- 递归调用的父问题和子问题没有交集
56+
57+
尝试用递归去解决相同的树
58+
59+
1. 分解为子问题,相同的树分解为左子是否相同,右子是否相同
60+
2. 递归出口: 当树高度为 1 时,判断递归出口
61+
62+
### 代码
63+
64+
语言支持:JS, Go, PHP
65+
66+
JS Code:
67+
68+
```js
69+
var isSameTree = function (p, q) {
70+
if (!p || !q) {
71+
return !p && !q;
72+
}
73+
return (
74+
p.val === q.val &&
75+
isSameTree(p.left, q.left) &&
76+
isSameTree(p.right, q.right)
77+
);
78+
};
79+
```
80+
81+
Go Code:
82+
83+
```go
84+
func isSameTree(p *TreeNode, q *TreeNode) bool {
85+
if p == nil || q == nil {
86+
return p==nil&&q==nil
87+
}
88+
return p.Val == q.Val && isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)
89+
}
90+
```
91+
92+
PHP Code:
93+
94+
```php
95+
class Solution
96+
{
97+
98+
/**
99+
* @param TreeNode $p
100+
* @param TreeNode $q
101+
* @return Boolean
102+
*/
103+
function isSameTree($p, $q)
104+
{
105+
if (!$p || !$q) {
106+
return !$p && !$q;
107+
}
108+
return $p->val == $q->val &&
109+
$this->isSameTree($p->left, $q->left) &&
110+
$this->isSameTree($p->right, $q->right);
111+
}
112+
}
113+
```
114+
115+
**复杂度分析**
116+
117+
- 时间复杂度:$O(N)$,其中 N 为树的节点数。
118+
- 空间复杂度:$O(h)$,其中 h 为树的高度。
119+
120+
## 层序遍历
121+
122+
### 思路
123+
124+
判断两棵树是否相同,只需要判断树的整个结构相同, 判断树的结构是否相同,只需要判断树的每层内容是否相同。
125+
126+
### 代码
127+
128+
语言支持:JS
129+
130+
JS Code:
131+
132+
```js
133+
var isSameTree = function (p, q) {
134+
let curLevelA = [p];
135+
let curLevelB = [q];
136+
137+
while (curLevelA.length && curLevelB.length) {
138+
let nextLevelA = [];
139+
let nextLevelB = [];
140+
const isOK = isSameCurLevel(curLevelA, curLevelB, nextLevelA, nextLevelB);
141+
if (isOK) {
142+
curLevelA = nextLevelA;
143+
curLevelB = nextLevelB;
144+
} else {
145+
return false;
146+
}
147+
}
148+
149+
return true;
150+
};
151+
152+
function isSameCurLevel(curLevelA, curLevelB, nextLevelA, nextLevelB) {
153+
if (curLevelA.length !== curLevelB.length) {
154+
return false;
155+
}
156+
for (let i = 0; i < curLevelA.length; i++) {
157+
if (!isSameNode(curLevelA[i], curLevelB[i])) {
158+
return false;
159+
}
160+
curLevelA[i] && nextLevelA.push(curLevelA[i].left, curLevelA[i].right);
161+
curLevelB[i] && nextLevelB.push(curLevelB[i].left, curLevelB[i].right);
162+
}
163+
return true;
164+
}
165+
166+
function isSameNode(nodeA, nodeB) {
167+
if (!nodeA || !nodeB) {
168+
return nodeA === nodeB;
169+
}
170+
return nodeA.val === nodeB.val;
171+
// return nodeA === nodeB || (nodeA && nodeB && nodeA.val === nodeB.val);
172+
}
173+
```
174+
175+
**复杂度分析**
176+
177+
- 时间复杂度:$O(N)$,其中 N 为树的节点数。
178+
- 空间复杂度:$O(Q)$,其中 Q 为队列的长度最大值,在这里不会超过相邻两层的节点数的最大值。
179+
180+
## 前中序确定一棵树
181+
182+
### 思路
183+
184+
前序和中序的遍历结果确定一棵树,那么当两棵树前序遍历和中序遍历结果都相同,那是否说明两棵树也相同。
185+
186+
### 代码
187+
188+
语言支持:JS
189+
190+
JS Code:
191+
192+
```js
193+
var isSameTree = function (p, q) {
194+
const preorderP = preorder(p, []);
195+
const preorderQ = preorder(q, []);
196+
const inorderP = inorder(p, []);
197+
const inorderQ = inorder(q, []);
198+
return (
199+
preorderP.join("") === preorderQ.join("") &&
200+
inorderP.join("") === inorderQ.join("")
201+
);
202+
};
203+
204+
function preorder(root, arr) {
205+
if (root === null) {
206+
arr.push(" ");
207+
return arr;
208+
}
209+
arr.push(root.val);
210+
preorder(root.left, arr);
211+
preorder(root.right, arr);
212+
return arr;
213+
}
214+
215+
function inorder(root, arr) {
216+
if (root === null) {
217+
arr.push(" ");
218+
return arr;
219+
}
220+
inorder(root.left, arr);
221+
arr.push(root.val);
222+
inorder(root.right, arr);
223+
return arr;
224+
}
225+
```
226+
227+
**复杂度分析**
228+
229+
- 时间复杂度:$O(N)$,其中 N 为树的节点数。
230+
- 空间复杂度:使用了中序遍历的结果数组,因此空间复杂度为 $O(N)$,其中 N 为树的节点数。

0 commit comments

Comments
 (0)