Skip to content

Commit 37deef7

Browse files
committed
feat: add solutions to lc problem: No.0993
No.0993.Cousins in Binary Tree
1 parent 3a128b3 commit 37deef7

File tree

7 files changed

+320
-318
lines changed

7 files changed

+320
-318
lines changed

solution/0900-0999/0993.Cousins in Binary Tree/README.md

Lines changed: 130 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,25 @@
5555

5656
<!-- 这里可写通用的实现逻辑 -->
5757

58-
**1. BFS 实现**
58+
**方法一:BFS**
5959

60-
可以利用数组 p, d 记录每个节点对应的父节点以及深度
60+
我们定义一个队列 $q$,队列中存储的是节点和其父节点。初始时,将根节点和空节点放入队列中
6161

62-
**2. DFS 实现**
62+
每次从队列中取出一个节点,如果该节点的值为 $x$ 或 $y$,则记录该节点的父节点和深度。如果该节点的左右子节点不为空,则将左右子节点和该节点放入队列中。
63+
64+
当队列中所有节点都处理完毕后,如果 $x$ 和 $y$ 的深度相同且父节点不同,则返回 $true$,否则返回 $false$。
65+
66+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数。
67+
68+
**方法二:DFS**
69+
70+
我们设计一个函数 $dfs(root, fa, d)$,表示从根节点 $root$ 出发,其父节点为 $fa$,深度为 $d$,进行深度优先搜索。
71+
72+
在函数中,我们首先判断当前节点是否为空,如果为空,则直接返回。如果当前节点的值为 $x$ 或 $y$,则记录该节点的父节点和深度。然后对当前节点的左右子节点分别调用函数 $dfs$,其中父节点为当前节点,深度为当前深度加 $1$。即 $dfs(root.left, root, d + 1)$ 和 $dfs(root.right, root, d + 1)$。
73+
74+
当整棵二叉树遍历完毕后,如果 $x$ 和 $y$ 的深度相同且父节点不同,则返回 $true$,否则返回 $false$。
75+
76+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数。
6377

6478
<!-- tabs:start -->
6579

@@ -77,24 +91,24 @@ BFS:
7791
# self.left = left
7892
# self.right = right
7993
class Solution:
80-
def isCousins(self, root: TreeNode, x: int, y: int) -> bool:
81-
p = list(range(110))
82-
d = list(range(110))
83-
q = deque([root])
84-
i = 0
94+
def isCousins(self, root: Optional[TreeNode], x: int, y: int) -> bool:
95+
q = deque([(root, None)])
96+
d = 0
97+
p1 = p2 = None
98+
d1 = d2 = 0
8599
while q:
86-
n = len(q)
87-
for _ in range(n):
88-
node = q.popleft()
89-
d[node.val] = i
100+
for _ in range(len(q)):
101+
node, fa = q.popleft()
102+
if node.val == x:
103+
p1, d1 = fa, d
104+
if node.val == y:
105+
p2, d2 = fa, d
90106
if node.left:
91-
p[node.left.val] = node.val
92-
q.append(node.left)
107+
q.append((node.left, node))
93108
if node.right:
94-
q.append(node.right)
95-
p[node.right.val] = node.val
96-
i += 1
97-
return p[x] != p[y] and d[x] == d[y]
109+
q.append((node.right, node))
110+
d += 1
111+
return p1 != p2 and d1 == d2
98112
```
99113

100114
DFS:
@@ -107,22 +121,20 @@ DFS:
107121
# self.left = left
108122
# self.right = right
109123
class Solution:
110-
def isCousins(self, root: TreeNode, x: int, y: int) -> bool:
111-
p1 = p2 = d1 = d2 = None
112-
113-
def dfs(root, p, d):
124+
def isCousins(self, root: Optional[TreeNode], x: int, y: int) -> bool:
125+
def dfs(root, fa, d):
114126
if root is None:
115127
return
116-
nonlocal p1, p2, d1, d2, x, y
117128
if root.val == x:
118-
p1, d1 = p, d
129+
t[0] = (fa, d)
119130
if root.val == y:
120-
p2, d2 = p, d
131+
t[1] = (fa, d)
121132
dfs(root.left, root, d + 1)
122133
dfs(root.right, root, d + 1)
123134

135+
t = [None, None]
124136
dfs(root, None, 0)
125-
return p1 != p2 and d1 == d2
137+
return t[0][0] != t[1][0] and t[0][1] == t[1][1]
126138
```
127139

128140
### **Java**
@@ -149,28 +161,33 @@ BFS:
149161
*/
150162
class Solution {
151163
public boolean isCousins(TreeNode root, int x, int y) {
152-
int[] p = new int[110];
153-
int[] d = new int[110];
154-
Deque<TreeNode> q = new ArrayDeque<>();
155-
q.offer(root);
156-
int i = 0;
164+
TreeNode p1 = null, p2 = null;
165+
int d1 = 0, d2 = 0;
166+
Deque<TreeNode[]> q = new ArrayDeque<>();
167+
q.offer(new TreeNode[]{root, null});
168+
int d = 0;
157169
while (!q.isEmpty()) {
158-
int n = q.size();
159-
while (n-- > 0) {
160-
TreeNode node = q.poll();
161-
d[node.val] = i;
170+
for (int n = q.size(); n > 0; --n) {
171+
var p = q.poll();
172+
TreeNode node = p[0], fa = p[1];
173+
if (node.val == x) {
174+
p1 = fa;
175+
d1 = d;
176+
}
177+
if (node.val == y) {
178+
p2 = fa;
179+
d2 = d;
180+
}
162181
if (node.left != null) {
163-
q.offer(node.left);
164-
p[node.left.val] = node.val;
182+
q.offer(new TreeNode[]{node.left, node});
165183
}
166184
if (node.right != null) {
167-
q.offer(node.right);
168-
p[node.right.val] = node.val;
185+
q.offer(new TreeNode[]{node.right, node});
169186
}
170187
}
171-
++i;
188+
++d;
172189
}
173-
return p[x] != p[y] && d[x] == d[y];
190+
return p1 != p2 && d1 == d2;
174191
}
175192
}
176193
```
@@ -229,7 +246,7 @@ BFS:
229246

230247
```cpp
231248
/**
232-
* Definition for a binary tree node->
249+
* Definition for a binary tree node.
233250
* struct TreeNode {
234251
* int val;
235252
* TreeNode *left;
@@ -242,29 +259,34 @@ BFS:
242259
class Solution {
243260
public:
244261
bool isCousins(TreeNode* root, int x, int y) {
245-
vector<int> p(110);
246-
vector<int> d(110);
247-
queue<TreeNode*> q;
248-
q.push(root);
249-
int i = 0;
262+
TreeNode* p1 = nullptr;
263+
TreeNode* p2 = nullptr;
264+
int d1 = 0, d2 = 0;
265+
queue<pair<TreeNode*, TreeNode*>> q;
266+
q.emplace(root, nullptr);
267+
int d = 0;
250268
while (!q.empty()) {
251-
int n = q.size();
252-
while (n--) {
253-
auto node = q.front();
254-
d[node->val] = i;
269+
for (int n = q.size(); n; --n) {
270+
auto [node, fa] = q.front();
255271
q.pop();
272+
if (node->val == x) {
273+
p1 = fa;
274+
d1 = d;
275+
}
276+
if (node->val == y) {
277+
p2 = fa;
278+
d2 = d;
279+
}
256280
if (node->left) {
257-
q.push(node->left);
258-
p[node->left->val] = node->val;
281+
q.emplace(node->left, node);
259282
}
260283
if (node->right) {
261-
q.push(node->right);
262-
p[node->right->val] = node->val;
284+
q.emplace(node->right, node);
263285
}
264286
}
265-
++i;
287+
++d;
266288
}
267-
return p[x] != p[y] && d[x] == d[y];
289+
return p1 != p2 && d1 == d2;
268290
}
269291
};
270292
```
@@ -285,33 +307,27 @@ DFS:
285307
*/
286308
class Solution {
287309
public:
288-
TreeNode* p1;
289-
TreeNode* p2;
290-
int d1, d2;
291-
int x, y;
292-
293310
bool isCousins(TreeNode* root, int x, int y) {
294-
this->x = x;
295-
this->y = y;
311+
TreeNode* p1, *p2;
312+
int d1, d2;
313+
function<void(TreeNode*, TreeNode*, int)> dfs = [&](TreeNode* root, TreeNode* fa, int d) {
314+
if (!root) {
315+
return;
316+
}
317+
if (root->val == x) {
318+
p1 = fa;
319+
d1 = d;
320+
}
321+
if (root->val == y) {
322+
p2 = fa;
323+
d2 = d;
324+
}
325+
dfs(root->left, root, d + 1);
326+
dfs(root->right, root, d + 1);
327+
};
296328
dfs(root, nullptr, 0);
297329
return p1 != p2 && d1 == d2;
298330
}
299-
300-
void dfs(TreeNode* root, TreeNode* p, int d) {
301-
if (!root) return;
302-
if (root->val == x)
303-
{
304-
p1 = p;
305-
d1 = d;
306-
}
307-
if (root->val == y)
308-
{
309-
p2 = p;
310-
d2 = d;
311-
}
312-
dfs(root->left, root, d + 1);
313-
dfs(root->right, root, d + 1);
314-
}
315331
};
316332
```
317333

@@ -329,30 +345,31 @@ BFS:
329345
* }
330346
*/
331347
func isCousins(root *TreeNode, x int, y int) bool {
332-
p := make([]int, 110)
333-
d := make([]int, 110)
334-
var q []*TreeNode
335-
q = append(q, root)
336-
i := 0
348+
type pair struct{ node, fa *TreeNode }
349+
q := []pair{pair{root, nil}}
350+
var p1, p2 *TreeNode
351+
var d, d1, d2 int
337352
for len(q) > 0 {
338-
n := len(q)
339-
for n > 0 {
340-
node := q[0]
353+
for n := len(q); n > 0; n-- {
354+
p := q[0]
341355
q = q[1:]
342-
n--
343-
d[node.Val] = i
356+
node, fa := p.node, p.fa
357+
if node.Val == x {
358+
p1, d1 = fa, d
359+
}
360+
if node.Val == y {
361+
p2, d2 = fa, d
362+
}
344363
if node.Left != nil {
345-
q = append(q, node.Left)
346-
p[node.Left.Val] = node.Val
364+
q = append(q, pair{node.Left, node})
347365
}
348366
if node.Right != nil {
349-
q = append(q, node.Right)
350-
p[node.Right.Val] = node.Val
367+
q = append(q, pair{node.Right, node})
351368
}
352369
}
353-
i++
370+
d++
354371
}
355-
return p[x] != p[y] && d[x] == d[y]
372+
return p1 != p2 && d1 == d2
356373
}
357374
```
358375

@@ -367,30 +384,25 @@ DFS:
367384
* Right *TreeNode
368385
* }
369386
*/
370-
var p1 *TreeNode
371-
var p2 *TreeNode
372-
var d1 int
373-
var d2 int
374-
375387
func isCousins(root *TreeNode, x int, y int) bool {
376-
dfs(root, nil, x, y, 0)
377-
return p1 != p2 && d1 == d2
378-
}
379-
380-
func dfs(root, p *TreeNode, x, y, d int) {
381-
if root == nil {
382-
return
383-
}
384-
if root.Val == x {
385-
p1 = p
386-
d1 = d
387-
}
388-
if root.Val == y {
389-
p2 = p
390-
d2 = d
388+
var p1, p2 *TreeNode
389+
var d1, d2 int
390+
var dfs func(*TreeNode, *TreeNode, int)
391+
dfs = func(root *TreeNode, fa *TreeNode, d int) {
392+
if root == nil {
393+
return
394+
}
395+
if root.Val == x {
396+
p1, d1 = fa, d
397+
}
398+
if root.Val == y {
399+
p2, d2 = fa, d
400+
}
401+
dfs(root.Left, root, d+1)
402+
dfs(root.Right, root, d+1)
391403
}
392-
dfs(root.Left, root, x, y, d+1)
393-
dfs(root.Right, root, x, y, d+1)
404+
dfs(root, nil, 0)
405+
return p1 != p2 && d1 == d2
394406
}
395407
```
396408

0 commit comments

Comments
 (0)