Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problem: No.0993 #2324

Merged
merged 2 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 151 additions & 89 deletions solution/0900-0999/0993.Cousins in Binary Tree/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,21 @@
class Solution:
def isCousins(self, root: Optional[TreeNode], x: int, y: int) -> bool:
q = deque([(root, None)])
d = 0
depth = 0
p1 = p2 = None
d1 = d2 = 0
d1 = d2 = None
while q:
for _ in range(len(q)):
node, fa = q.popleft()
node, parent = q.popleft()
if node.val == x:
p1, d1 = fa, d
if node.val == y:
p2, d2 = fa, d
p1, d1 = parent, depth
elif node.val == y:
p2, d2 = parent, depth
if node.left:
q.append((node.left, node))
if node.right:
q.append((node.right, node))
d += 1
depth += 1
return p1 != p2 and d1 == d2
```

Expand All @@ -111,22 +111,20 @@ class Solution:
*/
class Solution {
public boolean isCousins(TreeNode root, int x, int y) {
TreeNode p1 = null, p2 = null;
int d1 = 0, d2 = 0;
Deque<TreeNode[]> q = new ArrayDeque<>();
q.offer(new TreeNode[] {root, null});
int d = 0;
while (!q.isEmpty()) {
int d1 = 0, d2 = 0;
TreeNode p1 = null, p2 = null;
for (int depth = 0; !q.isEmpty(); ++depth) {
for (int n = q.size(); n > 0; --n) {
var p = q.poll();
TreeNode node = p[0], fa = p[1];
TreeNode[] t = q.poll();
TreeNode node = t[0], parent = t[1];
if (node.val == x) {
p1 = fa;
d1 = d;
}
if (node.val == y) {
p2 = fa;
d2 = d;
d1 = depth;
p1 = parent;
} else if (node.val == y) {
d2 = depth;
p2 = parent;
}
if (node.left != null) {
q.offer(new TreeNode[] {node.left, node});
Expand All @@ -135,7 +133,6 @@ class Solution {
q.offer(new TreeNode[] {node.right, node});
}
}
++d;
}
return p1 != p2 && d1 == d2;
}
Expand All @@ -157,34 +154,30 @@ class Solution {
class Solution {
public:
bool isCousins(TreeNode* root, int x, int y) {
TreeNode* p1 = nullptr;
TreeNode* p2 = nullptr;
int d1 = 0, d2 = 0;
queue<pair<TreeNode*, TreeNode*>> q;
q.emplace(root, nullptr);
int d = 0;
while (!q.empty()) {
q.push({root, nullptr});
int d1 = 0, d2 = 0;
TreeNode* p1 = nullptr, *p2 = nullptr;
for (int depth = 0; q.size(); ++depth) {
for (int n = q.size(); n; --n) {
auto [node, fa] = q.front();
auto [node, parent] = q.front();
q.pop();
if (node->val == x) {
p1 = fa;
d1 = d;
}
if (node->val == y) {
p2 = fa;
d2 = d;
d1 = depth;
p1 = parent;
} else if (node->val == y) {
d2 = depth;
p2 = parent;
}
if (node->left) {
q.emplace(node->left, node);
q.push({node->left, node});
}
if (node->right) {
q.emplace(node->right, node);
q.push({node->right, node});
}
}
++d;
}
return p1 != p2 && d1 == d2;
return d1 == d2 && p1 != p2;
}
};
```
Expand All @@ -199,20 +192,18 @@ public:
* }
*/
func isCousins(root *TreeNode, x int, y int) bool {
type pair struct{ node, fa *TreeNode }
q := []pair{pair{root, nil}}
type pair struct{ node, parent *TreeNode }
var d1, d2 int
var p1, p2 *TreeNode
var d, d1, d2 int
for len(q) > 0 {
q := []pair{{root, nil}}
for depth := 0; len(q) > 0; depth++ {
for n := len(q); n > 0; n-- {
p := q[0]
node, parent := q[0].node, q[0].parent
q = q[1:]
node, fa := p.node, p.fa
if node.Val == x {
p1, d1 = fa, d
}
if node.Val == y {
p2, d2 = fa, d
d1, p1 = depth, parent
} else if node.Val == y {
d2, p2 = depth, parent
}
if node.Left != nil {
q = append(q, pair{node.Left, node})
Expand All @@ -221,19 +212,58 @@ func isCousins(root *TreeNode, x int, y int) bool {
q = append(q, pair{node.Right, node})
}
}
d++
}
return p1 != p2 && d1 == d2
return d1 == d2 && p1 != p2
}
```

```ts
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/

function isCousins(root: TreeNode | null, x: number, y: number): boolean {
let [d1, d2] = [0, 0];
let [p1, p2] = [null, null];
const q: [TreeNode, TreeNode][] = [[root, null]];
for (let depth = 0; q.length > 0; ++depth) {
const t: [TreeNode, TreeNode][] = [];
for (const [node, parent] of q) {
if (node.val === x) {
[d1, p1] = [depth, parent];
} else if (node.val === y) {
[d2, p2] = [depth, parent];
}
if (node.left) {
t.push([node.left, node]);
}
if (node.right) {
t.push([node.right, node]);
}
}
q.splice(0, q.length, ...t);
}
return d1 === d2 && p1 !== p2;
}
```

<!-- tabs:end -->

### 方法二:DFS

我们设计一个函数 $dfs(root, fa, d)$,表示从根节点 $root$ 出发,其父节点为 $fa$,深度为 $d$,进行深度优先搜索。
我们设计一个函数 $dfs(root, parent, depth)$,表示从根节点 $root$ 出发,其父节点为 $parent$,深度为 $depth$,进行深度优先搜索。

在函数中,我们首先判断当前节点是否为空,如果为空,则直接返回。如果当前节点的值为 $x$ 或 $y$,则记录该节点的父节点和深度。然后对当前节点的左右子节点分别调用函数 $dfs$,其中父节点为当前节点,深度为当前深度加 $1$。即 $dfs(root.left, root, d + 1)$ 和 $dfs(root.right, root, d + 1)$。
在函数中,我们首先判断当前节点是否为空,如果为空,则直接返回。如果当前节点的值为 $x$ 或 $y$,则记录该节点的父节点和深度。然后对当前节点的左右子节点分别调用函数 $dfs$,其中父节点为当前节点,深度为当前深度加 $1$。即 $dfs(root.left, root, depth + 1)$ 和 $dfs(root.right, root, depth + 1)$。

当整棵二叉树遍历完毕后,如果 $x$ 和 $y$ 的深度相同且父节点不同,则返回 $true$,否则返回 $false$。

Expand All @@ -250,19 +280,19 @@ func isCousins(root *TreeNode, x int, y int) bool {
# self.right = right
class Solution:
def isCousins(self, root: Optional[TreeNode], x: int, y: int) -> bool:
def dfs(root, fa, d):
def dfs(root, parent, depth):
if root is None:
return
if root.val == x:
t[0] = (fa, d)
if root.val == y:
t[1] = (fa, d)
dfs(root.left, root, d + 1)
dfs(root.right, root, d + 1)
st[0] = (parent, depth)
elif root.val == y:
st[1] = (parent, depth)
dfs(root.left, root, depth + 1)
dfs(root.right, root, depth + 1)

t = [None, None]
st = [None, None]
dfs(root, None, 0)
return t[0][0] != t[1][0] and t[0][1] == t[1][1]
return st[0][0] != st[1][0] and st[0][1] == st[1][1]
```

```java
Expand All @@ -283,8 +313,8 @@ class Solution:
*/
class Solution {
private int x, y;
private TreeNode p1, p2;
private int d1, d2;
private TreeNode p1, p2;

public boolean isCousins(TreeNode root, int x, int y) {
this.x = x;
Expand All @@ -293,20 +323,19 @@ class Solution {
return p1 != p2 && d1 == d2;
}

private void dfs(TreeNode root, TreeNode p, int d) {
private void dfs(TreeNode root, TreeNode parent, int depth) {
if (root == null) {
return;
}
if (root.val == x) {
p1 = p;
d1 = d;
}
if (root.val == y) {
p2 = p;
d2 = d;
d1 = depth;
p1 = parent;
} else if (root.val == y) {
d2 = depth;
p2 = parent;
}
dfs(root.left, root, d + 1);
dfs(root.right, root, d + 1);
dfs(root.left, root, depth + 1);
dfs(root.right, root, depth + 1);
}
}
```
Expand All @@ -326,22 +355,22 @@ class Solution {
class Solution {
public:
bool isCousins(TreeNode* root, int x, int y) {
TreeNode *p1, *p2;
int d1, d2;
function<void(TreeNode*, TreeNode*, int)> dfs = [&](TreeNode* root, TreeNode* fa, int d) {
TreeNode* p1;
TreeNode* p2;
function<void(TreeNode*, TreeNode*, int)> dfs = [&](TreeNode* root, TreeNode* parent, int depth) {
if (!root) {
return;
}
if (root->val == x) {
p1 = fa;
d1 = d;
d1 = depth;
p1 = parent;
} else if (root->val == y) {
d2 = depth;
p2 = parent;
}
if (root->val == y) {
p2 = fa;
d2 = d;
}
dfs(root->left, root, d + 1);
dfs(root->right, root, d + 1);
dfs(root->left, root, depth + 1);
dfs(root->right, root, depth + 1);
};
dfs(root, nullptr, 0);
return p1 != p2 && d1 == d2;
Expand All @@ -359,24 +388,57 @@ public:
* }
*/
func isCousins(root *TreeNode, x int, y int) bool {
var p1, p2 *TreeNode
var d1, d2 int
var dfs func(*TreeNode, *TreeNode, int)
dfs = func(root *TreeNode, fa *TreeNode, d int) {
var p1, p2 *TreeNode
var dfs func(root, parent *TreeNode, depth int)
dfs = func(root, parent *TreeNode, depth int) {
if root == nil {
return
}
if root.Val == x {
p1, d1 = fa, d
d1, p1 = depth, parent
} else if root.Val == y {
d2, p2 = depth, parent
}
if root.Val == y {
p2, d2 = fa, d
}
dfs(root.Left, root, d+1)
dfs(root.Right, root, d+1)
dfs(root.Left, root, depth+1)
dfs(root.Right, root, depth+1)
}
dfs(root, nil, 0)
return p1 != p2 && d1 == d2
return d1 == d2 && p1 != p2
}
```

```ts
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/

function isCousins(root: TreeNode | null, x: number, y: number): boolean {
let [d1, d2, p1, p2] = [0, 0, null, null];
const dfs = (root: TreeNode | null, parent: TreeNode | null, depth: number) => {
if (!root) {
return;
}
if (root.val === x) {
[d1, p1] = [depth, parent];
} else if (root.val === y) {
[d2, p2] = [depth, parent];
}
dfs(root.left, root, depth + 1);
dfs(root.right, root, depth + 1);
};
dfs(root, null, 0);
return d1 === d2 && p1 !== p2;
}
```

Expand Down
Loading
Loading