diff --git a/solution/0600-0699/0624.Maximum Distance in Arrays/README.md b/solution/0600-0699/0624.Maximum Distance in Arrays/README.md index 30f9b82ea0797..0cf8d4f95562f 100644 --- a/solution/0600-0699/0624.Maximum Distance in Arrays/README.md +++ b/solution/0600-0699/0624.Maximum Distance in Arrays/README.md @@ -64,7 +64,7 @@ tags: 我们注意到,最大距离一定是两个数组中的一个最大值和另一个最小值之间的距离。因此,我们可以维护两个变量 $\textit{mi}$ 和 $\textit{mx}$,分别表示已经遍历过的数组中的最小值和最大值。初始时 $\textit{mi}$ 和 $\textit{mx}$ 分别为第一个数组的第一个元素和最后一个元素。 -接下来,我们从第二个数组开始遍历,对于每个数组,我们首先计算当前数组的第一个元素和 $\textit{mx}$ 之间的距离,以及当前数组的最后一个元素和 $\textit{mi}$ 之间的距离,然后更新最大距离。同时,我们更新 $\textit{mi}$ 和 $\textit{mx}$ 为当前数组的第一个元素和最后一个元素。 +接下来,我们从第二个数组开始遍历,对于每个数组,我们首先计算当前数组的第一个元素和 $\textit{mx}$ 之间的距离,以及当前数组的最后一个元素和 $\textit{mi}$ 之间的距离,然后更新最大距离。同时,我们更新 $\textit{mi} = \min(\textit{mi}, \textit{arr}[0])$ 和 $\textit{mx} = \max(\textit{mx}, \textit{arr}[\textit{size} - 1])$。 遍历结束后,即可得到最大距离。 diff --git a/solution/0600-0699/0624.Maximum Distance in Arrays/README_EN.md b/solution/0600-0699/0624.Maximum Distance in Arrays/README_EN.md index b6c7a33b09bba..5698f5ae9bf3f 100644 --- a/solution/0600-0699/0624.Maximum Distance in Arrays/README_EN.md +++ b/solution/0600-0699/0624.Maximum Distance in Arrays/README_EN.md @@ -61,7 +61,7 @@ tags: We notice that the maximum distance must be the distance between the maximum value in one array and the minimum value in another array. Therefore, we can maintain two variables $\textit{mi}$ and $\textit{mx}$, representing the minimum and maximum values of the arrays we have traversed. Initially, $\textit{mi}$ and $\textit{mx}$ are the first and last elements of the first array, respectively. -Next, we traverse from the second array. For each array, we first calculate the distance between the first element of the current array and $\textit{mx}$, and the distance between the last element of the current array and $\textit{mi}$. Then, we update the maximum distance. At the same time, we update $\textit{mi}$ and $\textit{mx}$ to be the first and last elements of the current array. +Next, we traverse from the second array. For each array, we first calculate the distance between the first element of the current array and $\textit{mx}$, and the distance between the last element of the current array and $\textit{mi}$. Then, we update the maximum distance. At the same time, we update $\textit{mi} = \min(\textit{mi}, \textit{arr}[0])$ and $\textit{mx} = \max(\textit{mx}, \textit{arr}[\textit{size} - 1])$. After traversing all arrays, we get the maximum distance. diff --git a/solution/0600-0699/0657.Robot Return to Origin/README.md b/solution/0600-0699/0657.Robot Return to Origin/README.md index 448f42a1a382b..d55967f84ce3a 100644 --- a/solution/0600-0699/0657.Robot Return to Origin/README.md +++ b/solution/0600-0699/0657.Robot Return to Origin/README.md @@ -56,7 +56,20 @@ tags: -### 方法一 +### 方法一:维护坐标 + +我们可以维护一个坐标 $(x, y)$,分别表示机器人在水平方向和竖直方向上的移动。 + +遍历字符串 $\textit{moves}$,根据当前字符的不同,更新坐标 $(x, y)$: + +- 如果当前字符是 `'U'`,则 $y$ 加 $1$; +- 如果当前字符是 `'D'`,则 $y$ 减 $1$; +- 如果当前字符是 `'L'`,则 $x$ 减 $1$; +- 如果当前字符是 `'R'`,则 $x$ 加 $1$。 + +最后,判断 $x$ 和 $y$ 是否都为 $0$ 即可。 + +时间复杂度 $O(n)$,其中 $n$ 为字符串 $\textit{moves}$ 的长度。空间复杂度 $O(1)$。 @@ -67,14 +80,15 @@ class Solution: def judgeCircle(self, moves: str) -> bool: x = y = 0 for c in moves: - if c == 'R': - x += 1 - elif c == 'L': - x -= 1 - elif c == 'U': - y += 1 - elif c == 'D': - y -= 1 + match c: + case "U": + y += 1 + case "D": + y -= 1 + case "L": + x -= 1 + case "R": + x += 1 return x == 0 and y == 0 ``` @@ -84,43 +98,104 @@ class Solution: class Solution { public boolean judgeCircle(String moves) { int x = 0, y = 0; - for (int i = 0; i < moves.length(); ++i) { - char c = moves.charAt(i); - if (c == 'R') - ++x; - else if (c == 'L') - --x; - else if (c == 'U') - ++y; - else if (c == 'D') - --y; + for (char c : moves.toCharArray()) { + switch (c) { + case 'U' -> y++; + case 'D' -> y--; + case 'L' -> x--; + case 'R' -> x++; + } } return x == 0 && y == 0; } } ``` +#### C++ + +```cpp +class Solution { +public: + bool judgeCircle(string moves) { + int x = 0, y = 0; + for (char c : moves) { + switch (c) { + case 'U': y++; break; + case 'D': y--; break; + case 'L': x--; break; + case 'R': x++; break; + } + } + return x == 0 && y == 0; + } +}; +``` + +#### Go + +```go +func judgeCircle(moves string) bool { + x, y := 0, 0 + for _, c := range moves { + switch c { + case 'U': + y++ + case 'D': + y-- + case 'L': + x-- + case 'R': + x++ + } + } + return x == 0 && y == 0 +} +``` + #### TypeScript ```ts function judgeCircle(moves: string): boolean { - let x = 0, - y = 0; - const dir = { - R: [1, 0], - L: [-1, 0], - U: [0, 1], - D: [0, -1], - }; - for (let u of moves) { - const [dx, dy] = dir[u]; - x += dx; - y += dy; + let [x, y] = [0, 0]; + for (const c of moves) { + if (c === 'U') { + y++; + } else if (c === 'D') { + y--; + } else if (c === 'L') { + x--; + } else { + x++; + } } - return !x && !y; + return x === 0 && y === 0; } ``` +#### JavaScript + +```js +/** + * @param {string} moves + * @return {boolean} + */ +var judgeCircle = function (moves) { + let [x, y] = [0, 0]; + for (const c of moves) { + if (c === 'U') { + y++; + } else if (c === 'D') { + y--; + } else if (c === 'L') { + x--; + } else { + x++; + } + } + return x === 0 && y === 0; +}; +``` + diff --git a/solution/0600-0699/0657.Robot Return to Origin/README_EN.md b/solution/0600-0699/0657.Robot Return to Origin/README_EN.md index 64ea40b8c8cb6..9b7e6d954c7eb 100644 --- a/solution/0600-0699/0657.Robot Return to Origin/README_EN.md +++ b/solution/0600-0699/0657.Robot Return to Origin/README_EN.md @@ -56,7 +56,20 @@ tags: -### Solution 1 +### Solution 1: Maintain Coordinates + +We can maintain a coordinate $(x, y)$ to represent the robot's movement in the horizontal and vertical directions. + +Traverse the string $\textit{moves}$ and update the coordinate $(x, y)$ based on the current character: + +- If the current character is `'U'`, then $y$ increases by $1$; +- If the current character is `'D'$, then $y$ decreases by $1$; +- If the current character is `'L'$, then $x$ decreases by $1$; +- If the current character is `'R'$, then $x$ increases by $1$. + +Finally, check if both $x$ and $y$ are $0$. + +The time complexity is $O(n)$, where $n$ is the length of the string $\textit{moves}$. The space complexity is $O(1)$. @@ -67,14 +80,15 @@ class Solution: def judgeCircle(self, moves: str) -> bool: x = y = 0 for c in moves: - if c == 'R': - x += 1 - elif c == 'L': - x -= 1 - elif c == 'U': - y += 1 - elif c == 'D': - y -= 1 + match c: + case "U": + y += 1 + case "D": + y -= 1 + case "L": + x -= 1 + case "R": + x += 1 return x == 0 and y == 0 ``` @@ -84,43 +98,104 @@ class Solution: class Solution { public boolean judgeCircle(String moves) { int x = 0, y = 0; - for (int i = 0; i < moves.length(); ++i) { - char c = moves.charAt(i); - if (c == 'R') - ++x; - else if (c == 'L') - --x; - else if (c == 'U') - ++y; - else if (c == 'D') - --y; + for (char c : moves.toCharArray()) { + switch (c) { + case 'U' -> y++; + case 'D' -> y--; + case 'L' -> x--; + case 'R' -> x++; + } } return x == 0 && y == 0; } } ``` +#### C++ + +```cpp +class Solution { +public: + bool judgeCircle(string moves) { + int x = 0, y = 0; + for (char c : moves) { + switch (c) { + case 'U': y++; break; + case 'D': y--; break; + case 'L': x--; break; + case 'R': x++; break; + } + } + return x == 0 && y == 0; + } +}; +``` + +#### Go + +```go +func judgeCircle(moves string) bool { + x, y := 0, 0 + for _, c := range moves { + switch c { + case 'U': + y++ + case 'D': + y-- + case 'L': + x-- + case 'R': + x++ + } + } + return x == 0 && y == 0 +} +``` + #### TypeScript ```ts function judgeCircle(moves: string): boolean { - let x = 0, - y = 0; - const dir = { - R: [1, 0], - L: [-1, 0], - U: [0, 1], - D: [0, -1], - }; - for (let u of moves) { - const [dx, dy] = dir[u]; - x += dx; - y += dy; + let [x, y] = [0, 0]; + for (const c of moves) { + if (c === 'U') { + y++; + } else if (c === 'D') { + y--; + } else if (c === 'L') { + x--; + } else { + x++; + } } - return !x && !y; + return x === 0 && y === 0; } ``` +#### JavaScript + +```js +/** + * @param {string} moves + * @return {boolean} + */ +var judgeCircle = function (moves) { + let [x, y] = [0, 0]; + for (const c of moves) { + if (c === 'U') { + y++; + } else if (c === 'D') { + y--; + } else if (c === 'L') { + x--; + } else { + x++; + } + } + return x === 0 && y === 0; +}; +``` + diff --git a/solution/0600-0699/0657.Robot Return to Origin/Solution.cpp b/solution/0600-0699/0657.Robot Return to Origin/Solution.cpp new file mode 100644 index 0000000000000..c939c0d280c88 --- /dev/null +++ b/solution/0600-0699/0657.Robot Return to Origin/Solution.cpp @@ -0,0 +1,15 @@ +class Solution { +public: + bool judgeCircle(string moves) { + int x = 0, y = 0; + for (char c : moves) { + switch (c) { + case 'U': y++; break; + case 'D': y--; break; + case 'L': x--; break; + case 'R': x++; break; + } + } + return x == 0 && y == 0; + } +}; diff --git a/solution/0600-0699/0657.Robot Return to Origin/Solution.go b/solution/0600-0699/0657.Robot Return to Origin/Solution.go new file mode 100644 index 0000000000000..239fb6e9bb691 --- /dev/null +++ b/solution/0600-0699/0657.Robot Return to Origin/Solution.go @@ -0,0 +1,16 @@ +func judgeCircle(moves string) bool { + x, y := 0, 0 + for _, c := range moves { + switch c { + case 'U': + y++ + case 'D': + y-- + case 'L': + x-- + case 'R': + x++ + } + } + return x == 0 && y == 0 +} diff --git a/solution/0600-0699/0657.Robot Return to Origin/Solution.java b/solution/0600-0699/0657.Robot Return to Origin/Solution.java index 71d6bd1b40e16..350d3d83ba7d8 100644 --- a/solution/0600-0699/0657.Robot Return to Origin/Solution.java +++ b/solution/0600-0699/0657.Robot Return to Origin/Solution.java @@ -1,17 +1,14 @@ class Solution { public boolean judgeCircle(String moves) { int x = 0, y = 0; - for (int i = 0; i < moves.length(); ++i) { - char c = moves.charAt(i); - if (c == 'R') - ++x; - else if (c == 'L') - --x; - else if (c == 'U') - ++y; - else if (c == 'D') - --y; + for (char c : moves.toCharArray()) { + switch (c) { + case 'U' -> y++; + case 'D' -> y--; + case 'L' -> x--; + case 'R' -> x++; + } } return x == 0 && y == 0; } -} \ No newline at end of file +} diff --git a/solution/0600-0699/0657.Robot Return to Origin/Solution.js b/solution/0600-0699/0657.Robot Return to Origin/Solution.js new file mode 100644 index 0000000000000..32b5a65427ecb --- /dev/null +++ b/solution/0600-0699/0657.Robot Return to Origin/Solution.js @@ -0,0 +1,19 @@ +/** + * @param {string} moves + * @return {boolean} + */ +var judgeCircle = function (moves) { + let [x, y] = [0, 0]; + for (const c of moves) { + if (c === 'U') { + y++; + } else if (c === 'D') { + y--; + } else if (c === 'L') { + x--; + } else { + x++; + } + } + return x === 0 && y === 0; +}; diff --git a/solution/0600-0699/0657.Robot Return to Origin/Solution.py b/solution/0600-0699/0657.Robot Return to Origin/Solution.py index f2b5aacd3cbf0..437f58f6dfde0 100644 --- a/solution/0600-0699/0657.Robot Return to Origin/Solution.py +++ b/solution/0600-0699/0657.Robot Return to Origin/Solution.py @@ -2,12 +2,13 @@ class Solution: def judgeCircle(self, moves: str) -> bool: x = y = 0 for c in moves: - if c == 'R': - x += 1 - elif c == 'L': - x -= 1 - elif c == 'U': - y += 1 - elif c == 'D': - y -= 1 + match c: + case "U": + y += 1 + case "D": + y -= 1 + case "L": + x -= 1 + case "R": + x += 1 return x == 0 and y == 0 diff --git a/solution/0600-0699/0657.Robot Return to Origin/Solution.ts b/solution/0600-0699/0657.Robot Return to Origin/Solution.ts index 3cd6874204f84..c02d647362cbb 100644 --- a/solution/0600-0699/0657.Robot Return to Origin/Solution.ts +++ b/solution/0600-0699/0657.Robot Return to Origin/Solution.ts @@ -1,16 +1,15 @@ function judgeCircle(moves: string): boolean { - let x = 0, - y = 0; - const dir = { - R: [1, 0], - L: [-1, 0], - U: [0, 1], - D: [0, -1], - }; - for (let u of moves) { - const [dx, dy] = dir[u]; - x += dx; - y += dy; + let [x, y] = [0, 0]; + for (const c of moves) { + if (c === 'U') { + y++; + } else if (c === 'D') { + y--; + } else if (c === 'L') { + x--; + } else { + x++; + } } - return !x && !y; + return x === 0 && y === 0; } diff --git a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/README.md b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/README.md index 40b7e3af505c6..302ec888b0419 100644 --- a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/README.md +++ b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/README.md @@ -68,9 +68,11 @@ tags: ### 方法一:DFS + 哈希表 -我们先用 DFS 遍历整棵树,记录每个结点的父结点,然后从目标结点开始,向上、向下分别搜索距离为 $k$ 的结点,添加到答案数组中。 +我们先用 DFS 遍历整棵树,将每个节点的父节点保存到哈希表 $\textit{g}$ 中。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的结点数。 +接下来,我们再次用 DFS,从 $\textit{target}$ 出发,向上向下搜索距离为 $k$ 的节点,添加到结果数组中。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树的节点个数。 @@ -87,31 +89,27 @@ tags: class Solution: def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]: - def parents(root, prev): - nonlocal p + def dfs(root, fa): if root is None: return - p[root] = prev - parents(root.left, root) - parents(root.right, root) + g[root] = fa + dfs(root.left, root) + dfs(root.right, root) - def dfs(root, k): - nonlocal ans, vis - if root is None or root.val in vis: + def dfs2(root, fa, k): + if root is None: return - vis.add(root.val) if k == 0: ans.append(root.val) return - dfs(root.left, k - 1) - dfs(root.right, k - 1) - dfs(p[root], k - 1) + for nxt in (root.left, root.right, g[root]): + if nxt != fa: + dfs2(nxt, root, k - 1) - p = {} - parents(root, None) + g = {} + dfs(root, None) ans = [] - vis = set() - dfs(target, k) + dfs2(target, None, k) return ans ``` @@ -128,40 +126,37 @@ class Solution: * } */ class Solution { - private Map p; - private Set vis; - private List ans; + private Map g = new HashMap<>(); + private List ans = new ArrayList<>(); public List distanceK(TreeNode root, TreeNode target, int k) { - p = new HashMap<>(); - vis = new HashSet<>(); - ans = new ArrayList<>(); - parents(root, null); - dfs(target, k); + dfs(root, null); + dfs2(target, null, k); return ans; } - private void parents(TreeNode root, TreeNode prev) { + private void dfs(TreeNode root, TreeNode fa) { if (root == null) { return; } - p.put(root, prev); - parents(root.left, root); - parents(root.right, root); + g.put(root, fa); + dfs(root.left, root); + dfs(root.right, root); } - private void dfs(TreeNode root, int k) { - if (root == null || vis.contains(root.val)) { + private void dfs2(TreeNode root, TreeNode fa, int k) { + if (root == null) { return; } - vis.add(root.val); if (k == 0) { ans.add(root.val); return; } - dfs(root.left, k - 1); - dfs(root.right, k - 1); - dfs(p.get(root), k - 1); + for (TreeNode nxt : new TreeNode[] {root.left, root.right, g.get(root)}) { + if (nxt != fa) { + dfs2(nxt, root, k - 1); + } + } } } ``` @@ -180,126 +175,75 @@ class Solution { */ class Solution { public: - unordered_map p; - unordered_set vis; - vector ans; - vector distanceK(TreeNode* root, TreeNode* target, int k) { - parents(root, nullptr); - dfs(target, k); + unordered_map g; + vector ans; + + auto dfs = [&](this auto&& dfs, TreeNode* node, TreeNode* fa) { + if (!node) return; + g[node] = fa; + dfs(node->left, node); + dfs(node->right, node); + }; + + auto dfs2 = [&](this auto&& dfs2, TreeNode* node, TreeNode* fa, int k) { + if (!node) return; + if (k == 0) { + ans.push_back(node->val); + return; + } + for (auto&& nxt : {node->left, node->right, g[node]}) { + if (nxt != fa) { + dfs2(nxt, node, k - 1); + } + } + }; + + dfs(root, nullptr); + dfs2(target, nullptr, k); return ans; } - - void parents(TreeNode* root, TreeNode* prev) { - if (!root) return; - p[root] = prev; - parents(root->left, root); - parents(root->right, root); - } - - void dfs(TreeNode* root, int k) { - if (!root || vis.count(root->val)) return; - vis.insert(root->val); - if (k == 0) { - ans.push_back(root->val); - return; - } - dfs(root->left, k - 1); - dfs(root->right, k - 1); - dfs(p[root], k - 1); - } }; ``` #### Go ```go -/** - * Definition for a binary tree node. - * type TreeNode struct { - * Val int - * Left *TreeNode - * Right *TreeNode - * } - */ func distanceK(root *TreeNode, target *TreeNode, k int) []int { - p := make(map[*TreeNode]*TreeNode) - vis := make(map[int]bool) - var ans []int - var parents func(root, prev *TreeNode) - parents = func(root, prev *TreeNode) { - if root == nil { + g := make(map[*TreeNode]*TreeNode) + ans := []int{} + + var dfs func(node, fa *TreeNode) + dfs = func(node, fa *TreeNode) { + if node == nil { return } - p[root] = prev - parents(root.Left, root) - parents(root.Right, root) + g[node] = fa + dfs(node.Left, node) + dfs(node.Right, node) } - parents(root, nil) - var dfs func(root *TreeNode, k int) - dfs = func(root *TreeNode, k int) { - if root == nil || vis[root.Val] { + + var dfs2 func(node, fa *TreeNode, k int) + dfs2 = func(node, fa *TreeNode, k int) { + if node == nil { return } - vis[root.Val] = true if k == 0 { - ans = append(ans, root.Val) + ans = append(ans, node.Val) return } - dfs(root.Left, k-1) - dfs(root.Right, k-1) - dfs(p[root], k-1) + for _, nxt := range []*TreeNode{node.Left, node.Right, g[node]} { + if nxt != fa { + dfs2(nxt, node, k-1) + } + } } - dfs(target, k) - return ans -} -``` - - - - - - - -### 方法二 - - -#### Python3 + dfs(root, nil) + dfs2(target, nil, k) -```python -# Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None - - -class Solution: - def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]: - def dfs1(root, fa): - if root is None: - return - p[root] = fa - dfs1(root.left, root) - dfs1(root.right, root) - - def dfs2(root, fa, k): - if root is None: - return - if k == 0: - ans.append(root.val) - return - for nxt in (root.left, root.right, p[root]): - if nxt != fa: - dfs2(nxt, root, k - 1) - - p = {} - dfs1(root, None) - ans = [] - dfs2(target, None, k) - return ans + return ans +} ``` #### TypeScript @@ -320,43 +264,36 @@ class Solution: */ function distanceK(root: TreeNode | null, target: TreeNode | null, k: number): number[] { - if (!root) return [0]; - - const g: Record = {}; - - const dfs = (node: TreeNode | null, parent: TreeNode | null = null) => { - if (!node) return; - - g[node.val] ??= []; - if (parent) g[node.val].push(parent.val); - if (node.left) g[node.val].push(node.left.val); - if (node.right) g[node.val].push(node.right.val); + const g = new Map(); + const ans: number[] = []; + const dfs = (node: TreeNode | null, fa: TreeNode | null) => { + if (!node) { + return; + } + g.set(node, fa); dfs(node.left, node); dfs(node.right, node); }; - dfs(root); - - const vis = new Set(); - let q = [target!.val]; - - while (q.length) { - if (!k--) return q; - - const nextQ: number[] = []; - - for (const x of q) { - if (vis.has(x)) continue; - - vis.add(x); - nextQ.push(...g[x].filter(x => !vis.has(x))); + const dfs2 = (node: TreeNode | null, fa: TreeNode | null, k: number) => { + if (!node) { + return; } + if (k === 0) { + ans.push(node.val); + return; + } + for (const nxt of [node.left, node.right, g.get(node) || null]) { + if (nxt !== fa) { + dfs2(nxt, node, k - 1); + } + } + }; - q = nextQ; - } - - return []; + dfs(root, null); + dfs2(target, null, k); + return ans; } ``` diff --git a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/README_EN.md b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/README_EN.md index fe20910da530f..ef15cf588ea37 100644 --- a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/README_EN.md +++ b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/README_EN.md @@ -57,7 +57,13 @@ Explanation: The nodes that are a distance 2 from the target node (with value 5) -### Solution 1 +### Solution 1: DFS + Hash Table + +We first use DFS to traverse the entire tree and save each node's parent node in the hash table $\textit{g}$. + +Next, we use DFS again, starting from $\textit{target}$, to search for nodes at a distance of $k$ both upwards and downwards, and add them to the result array. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree. @@ -74,31 +80,27 @@ Explanation: The nodes that are a distance 2 from the target node (with value 5) class Solution: def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]: - def parents(root, prev): - nonlocal p + def dfs(root, fa): if root is None: return - p[root] = prev - parents(root.left, root) - parents(root.right, root) + g[root] = fa + dfs(root.left, root) + dfs(root.right, root) - def dfs(root, k): - nonlocal ans, vis - if root is None or root.val in vis: + def dfs2(root, fa, k): + if root is None: return - vis.add(root.val) if k == 0: ans.append(root.val) return - dfs(root.left, k - 1) - dfs(root.right, k - 1) - dfs(p[root], k - 1) + for nxt in (root.left, root.right, g[root]): + if nxt != fa: + dfs2(nxt, root, k - 1) - p = {} - parents(root, None) + g = {} + dfs(root, None) ans = [] - vis = set() - dfs(target, k) + dfs2(target, None, k) return ans ``` @@ -115,40 +117,37 @@ class Solution: * } */ class Solution { - private Map p; - private Set vis; - private List ans; + private Map g = new HashMap<>(); + private List ans = new ArrayList<>(); public List distanceK(TreeNode root, TreeNode target, int k) { - p = new HashMap<>(); - vis = new HashSet<>(); - ans = new ArrayList<>(); - parents(root, null); - dfs(target, k); + dfs(root, null); + dfs2(target, null, k); return ans; } - private void parents(TreeNode root, TreeNode prev) { + private void dfs(TreeNode root, TreeNode fa) { if (root == null) { return; } - p.put(root, prev); - parents(root.left, root); - parents(root.right, root); + g.put(root, fa); + dfs(root.left, root); + dfs(root.right, root); } - private void dfs(TreeNode root, int k) { - if (root == null || vis.contains(root.val)) { + private void dfs2(TreeNode root, TreeNode fa, int k) { + if (root == null) { return; } - vis.add(root.val); if (k == 0) { ans.add(root.val); return; } - dfs(root.left, k - 1); - dfs(root.right, k - 1); - dfs(p.get(root), k - 1); + for (TreeNode nxt : new TreeNode[] {root.left, root.right, g.get(root)}) { + if (nxt != fa) { + dfs2(nxt, root, k - 1); + } + } } } ``` @@ -167,77 +166,73 @@ class Solution { */ class Solution { public: - unordered_map p; - unordered_set vis; - vector ans; - vector distanceK(TreeNode* root, TreeNode* target, int k) { - parents(root, nullptr); - dfs(target, k); + unordered_map g; + vector ans; + + auto dfs = [&](this auto&& dfs, TreeNode* node, TreeNode* fa) { + if (!node) return; + g[node] = fa; + dfs(node->left, node); + dfs(node->right, node); + }; + + auto dfs2 = [&](this auto&& dfs2, TreeNode* node, TreeNode* fa, int k) { + if (!node) return; + if (k == 0) { + ans.push_back(node->val); + return; + } + for (auto&& nxt : {node->left, node->right, g[node]}) { + if (nxt != fa) { + dfs2(nxt, node, k - 1); + } + } + }; + + dfs(root, nullptr); + dfs2(target, nullptr, k); return ans; } - - void parents(TreeNode* root, TreeNode* prev) { - if (!root) return; - p[root] = prev; - parents(root->left, root); - parents(root->right, root); - } - - void dfs(TreeNode* root, int k) { - if (!root || vis.count(root->val)) return; - vis.insert(root->val); - if (k == 0) { - ans.push_back(root->val); - return; - } - dfs(root->left, k - 1); - dfs(root->right, k - 1); - dfs(p[root], k - 1); - } }; ``` #### Go ```go -/** - * Definition for a binary tree node. - * type TreeNode struct { - * Val int - * Left *TreeNode - * Right *TreeNode - * } - */ func distanceK(root *TreeNode, target *TreeNode, k int) []int { - p := make(map[*TreeNode]*TreeNode) - vis := make(map[int]bool) - var ans []int - var parents func(root, prev *TreeNode) - parents = func(root, prev *TreeNode) { - if root == nil { + g := make(map[*TreeNode]*TreeNode) + ans := []int{} + + var dfs func(node, fa *TreeNode) + dfs = func(node, fa *TreeNode) { + if node == nil { return } - p[root] = prev - parents(root.Left, root) - parents(root.Right, root) + g[node] = fa + dfs(node.Left, node) + dfs(node.Right, node) } - parents(root, nil) - var dfs func(root *TreeNode, k int) - dfs = func(root *TreeNode, k int) { - if root == nil || vis[root.Val] { + + var dfs2 func(node, fa *TreeNode, k int) + dfs2 = func(node, fa *TreeNode, k int) { + if node == nil { return } - vis[root.Val] = true if k == 0 { - ans = append(ans, root.Val) + ans = append(ans, node.Val) return } - dfs(root.Left, k-1) - dfs(root.Right, k-1) - dfs(p[root], k-1) + for _, nxt := range []*TreeNode{node.Left, node.Right, g[node]} { + if nxt != fa { + dfs2(nxt, node, k-1) + } + } } - dfs(target, k) + + dfs(root, nil) + dfs2(target, nil, k) + return ans } ``` @@ -260,43 +255,36 @@ func distanceK(root *TreeNode, target *TreeNode, k int) []int { */ function distanceK(root: TreeNode | null, target: TreeNode | null, k: number): number[] { - if (!root) return [0]; - - const g: Record = {}; - - const dfs = (node: TreeNode | null, parent: TreeNode | null = null) => { - if (!node) return; - - g[node.val] ??= []; - if (parent) g[node.val].push(parent.val); - if (node.left) g[node.val].push(node.left.val); - if (node.right) g[node.val].push(node.right.val); + const g = new Map(); + const ans: number[] = []; + const dfs = (node: TreeNode | null, fa: TreeNode | null) => { + if (!node) { + return; + } + g.set(node, fa); dfs(node.left, node); dfs(node.right, node); }; - dfs(root); - - const vis = new Set(); - let q = [target!.val]; - - while (q.length) { - if (!k--) return q; - - const nextQ: number[] = []; - - for (const x of q) { - if (vis.has(x)) continue; - - vis.add(x); - nextQ.push(...g[x].filter(x => !vis.has(x))); + const dfs2 = (node: TreeNode | null, fa: TreeNode | null, k: number) => { + if (!node) { + return; } + if (k === 0) { + ans.push(node.val); + return; + } + for (const nxt of [node.left, node.right, g.get(node) || null]) { + if (nxt !== fa) { + dfs2(nxt, node, k - 1); + } + } + }; - q = nextQ; - } - - return []; + dfs(root, null); + dfs2(target, null, k); + return ans; } ``` @@ -304,51 +292,4 @@ function distanceK(root: TreeNode | null, target: TreeNode | null, k: number): n - - -### Solution 2 - - - -#### Python3 - -```python -# Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None - - -class Solution: - def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]: - def dfs1(root, fa): - if root is None: - return - p[root] = fa - dfs1(root.left, root) - dfs1(root.right, root) - - def dfs2(root, fa, k): - if root is None: - return - if k == 0: - ans.append(root.val) - return - for nxt in (root.left, root.right, p[root]): - if nxt != fa: - dfs2(nxt, root, k - 1) - - p = {} - dfs1(root, None) - ans = [] - dfs2(target, None, k) - return ans -``` - - - - - diff --git a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.cpp b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.cpp index fce0a0e63cbaf..0736b27fea430 100644 --- a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.cpp +++ b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.cpp @@ -9,32 +9,32 @@ */ class Solution { public: - unordered_map p; - unordered_set vis; - vector ans; - vector distanceK(TreeNode* root, TreeNode* target, int k) { - parents(root, nullptr); - dfs(target, k); - return ans; - } + unordered_map g; + vector ans; - void parents(TreeNode* root, TreeNode* prev) { - if (!root) return; - p[root] = prev; - parents(root->left, root); - parents(root->right, root); - } + auto dfs = [&](this auto&& dfs, TreeNode* node, TreeNode* fa) { + if (!node) return; + g[node] = fa; + dfs(node->left, node); + dfs(node->right, node); + }; + + auto dfs2 = [&](this auto&& dfs2, TreeNode* node, TreeNode* fa, int k) { + if (!node) return; + if (k == 0) { + ans.push_back(node->val); + return; + } + for (auto&& nxt : {node->left, node->right, g[node]}) { + if (nxt != fa) { + dfs2(nxt, node, k - 1); + } + } + }; - void dfs(TreeNode* root, int k) { - if (!root || vis.count(root->val)) return; - vis.insert(root->val); - if (k == 0) { - ans.push_back(root->val); - return; - } - dfs(root->left, k - 1); - dfs(root->right, k - 1); - dfs(p[root], k - 1); + dfs(root, nullptr); + dfs2(target, nullptr, k); + return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.go b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.go index bcf10a98a0bfe..f1b7fb02a7c2e 100644 --- a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.go +++ b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.go @@ -1,39 +1,35 @@ -/** - * Definition for a binary tree node. - * type TreeNode struct { - * Val int - * Left *TreeNode - * Right *TreeNode - * } - */ func distanceK(root *TreeNode, target *TreeNode, k int) []int { - p := make(map[*TreeNode]*TreeNode) - vis := make(map[int]bool) - var ans []int - var parents func(root, prev *TreeNode) - parents = func(root, prev *TreeNode) { - if root == nil { + g := make(map[*TreeNode]*TreeNode) + ans := []int{} + + var dfs func(node, fa *TreeNode) + dfs = func(node, fa *TreeNode) { + if node == nil { return } - p[root] = prev - parents(root.Left, root) - parents(root.Right, root) + g[node] = fa + dfs(node.Left, node) + dfs(node.Right, node) } - parents(root, nil) - var dfs func(root *TreeNode, k int) - dfs = func(root *TreeNode, k int) { - if root == nil || vis[root.Val] { + + var dfs2 func(node, fa *TreeNode, k int) + dfs2 = func(node, fa *TreeNode, k int) { + if node == nil { return } - vis[root.Val] = true if k == 0 { - ans = append(ans, root.Val) + ans = append(ans, node.Val) return } - dfs(root.Left, k-1) - dfs(root.Right, k-1) - dfs(p[root], k-1) + for _, nxt := range []*TreeNode{node.Left, node.Right, g[node]} { + if nxt != fa { + dfs2(nxt, node, k-1) + } + } } - dfs(target, k) + + dfs(root, nil) + dfs2(target, nil, k) + return ans -} \ No newline at end of file +} diff --git a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.java b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.java index c8c45a78912ad..1d0fc332313a5 100644 --- a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.java +++ b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.java @@ -8,39 +8,36 @@ * } */ class Solution { - private Map p; - private Set vis; - private List ans; + private Map g = new HashMap<>(); + private List ans = new ArrayList<>(); public List distanceK(TreeNode root, TreeNode target, int k) { - p = new HashMap<>(); - vis = new HashSet<>(); - ans = new ArrayList<>(); - parents(root, null); - dfs(target, k); + dfs(root, null); + dfs2(target, null, k); return ans; } - private void parents(TreeNode root, TreeNode prev) { + private void dfs(TreeNode root, TreeNode fa) { if (root == null) { return; } - p.put(root, prev); - parents(root.left, root); - parents(root.right, root); + g.put(root, fa); + dfs(root.left, root); + dfs(root.right, root); } - private void dfs(TreeNode root, int k) { - if (root == null || vis.contains(root.val)) { + private void dfs2(TreeNode root, TreeNode fa, int k) { + if (root == null) { return; } - vis.add(root.val); if (k == 0) { ans.add(root.val); return; } - dfs(root.left, k - 1); - dfs(root.right, k - 1); - dfs(p.get(root), k - 1); + for (TreeNode nxt : new TreeNode[] {root.left, root.right, g.get(root)}) { + if (nxt != fa) { + dfs2(nxt, root, k - 1); + } + } } -} \ No newline at end of file +} diff --git a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.py b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.py index 7d89d6ac2f2c3..fb8c34e763115 100644 --- a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.py +++ b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.py @@ -8,29 +8,25 @@ class Solution: def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]: - def parents(root, prev): - nonlocal p + def dfs(root, fa): if root is None: return - p[root] = prev - parents(root.left, root) - parents(root.right, root) + g[root] = fa + dfs(root.left, root) + dfs(root.right, root) - def dfs(root, k): - nonlocal ans, vis - if root is None or root.val in vis: + def dfs2(root, fa, k): + if root is None: return - vis.add(root.val) if k == 0: ans.append(root.val) return - dfs(root.left, k - 1) - dfs(root.right, k - 1) - dfs(p[root], k - 1) + for nxt in (root.left, root.right, g[root]): + if nxt != fa: + dfs2(nxt, root, k - 1) - p = {} - parents(root, None) + g = {} + dfs(root, None) ans = [] - vis = set() - dfs(target, k) + dfs2(target, None, k) return ans diff --git a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.ts b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.ts index a95da51511601..f8495773a6b79 100644 --- a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.ts +++ b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution.ts @@ -13,41 +13,34 @@ */ function distanceK(root: TreeNode | null, target: TreeNode | null, k: number): number[] { - if (!root) return [0]; - - const g: Record = {}; - - const dfs = (node: TreeNode | null, parent: TreeNode | null = null) => { - if (!node) return; - - g[node.val] ??= []; - if (parent) g[node.val].push(parent.val); - if (node.left) g[node.val].push(node.left.val); - if (node.right) g[node.val].push(node.right.val); + const g = new Map(); + const ans: number[] = []; + const dfs = (node: TreeNode | null, fa: TreeNode | null) => { + if (!node) { + return; + } + g.set(node, fa); dfs(node.left, node); dfs(node.right, node); }; - dfs(root); - - const vis = new Set(); - let q = [target!.val]; - - while (q.length) { - if (!k--) return q; - - const nextQ: number[] = []; - - for (const x of q) { - if (vis.has(x)) continue; - - vis.add(x); - nextQ.push(...g[x].filter(x => !vis.has(x))); + const dfs2 = (node: TreeNode | null, fa: TreeNode | null, k: number) => { + if (!node) { + return; } + if (k === 0) { + ans.push(node.val); + return; + } + for (const nxt of [node.left, node.right, g.get(node) || null]) { + if (nxt !== fa) { + dfs2(nxt, node, k - 1); + } + } + }; - q = nextQ; - } - - return []; + dfs(root, null); + dfs2(target, null, k); + return ans; } diff --git a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution2.py b/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution2.py deleted file mode 100644 index e1d93b69d9498..0000000000000 --- a/solution/0800-0899/0863.All Nodes Distance K in Binary Tree/Solution2.py +++ /dev/null @@ -1,32 +0,0 @@ -# Definition for a binary tree node. -# class TreeNode: -# def __init__(self, x): -# self.val = x -# self.left = None -# self.right = None - - -class Solution: - def distanceK(self, root: TreeNode, target: TreeNode, k: int) -> List[int]: - def dfs1(root, fa): - if root is None: - return - p[root] = fa - dfs1(root.left, root) - dfs1(root.right, root) - - def dfs2(root, fa, k): - if root is None: - return - if k == 0: - ans.append(root.val) - return - for nxt in (root.left, root.right, p[root]): - if nxt != fa: - dfs2(nxt, root, k - 1) - - p = {} - dfs1(root, None) - ans = [] - dfs2(target, None, k) - return ans