diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md index b76306b4c8808..b7dc7b03596aa 100644 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md @@ -407,87 +407,188 @@ var getDirections = function (root, startValue, destValue) { -#### 方法二:DFS +### 方法二:最近公共祖先 + DFS(优化) + +我们可以从 $\textit{root}$ 出发,找到 $\textit{startValue}$ 和 $\textit{destValue}$ 的路径,记为 $\textit{pathToStart}$ 和 $\textit{pathToDest}$,然后去除 $\textit{pathToStart}$ 和 $\textit{pathToDest}$ 的最长公共前缀,此时 $\textit{pathToStart}$ 的路径长度就是答案中 $\textit{U}$ 的个数,而 $\textit{pathToDest}$ 的路径就是答案中的路径,我们只需要将这两个路径拼接起来即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树的节点数。 +#### Python3 + +```python +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right + + +class Solution: + def getDirections( + self, root: Optional[TreeNode], startValue: int, destValue: int + ) -> str: + def dfs(node: Optional[TreeNode], x: int, path: List[str]): + if node is None: + return False + if node.val == x: + return True + path.append("L") + if dfs(node.left, x, path): + return True + path[-1] = "R" + if dfs(node.right, x, path): + return True + path.pop() + return False + + path_to_start = [] + path_to_dest = [] + + dfs(root, startValue, path_to_start) + dfs(root, destValue, path_to_dest) + i = 0 + while ( + i < len(path_to_start) + and i < len(path_to_dest) + and path_to_start[i] == path_to_dest[i] + ): + i += 1 + return "U" * (len(path_to_start) - i) + "".join(path_to_dest[i:]) +``` + #### Java ```java -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode() {} - * TreeNode(int val) { this.val = val; } - * TreeNode(int val, TreeNode left, TreeNode right) { - * this.val = val; - * this.left = left; - * this.right = right; - * } - * } - */ class Solution { - static byte[] path = new byte[200_001]; - int strtLevel = -1; - int destLevel = -1; - int comnLevel = -1; - public String getDirections(TreeNode root, int startValue, int destValue) { - findPaths(root, startValue, destValue, 100_000); - int answerIdx = comnLevel; - for (int i = strtLevel; i > comnLevel; i--) { - path[--answerIdx] = 'U'; + StringBuilder pathToStart = new StringBuilder(); + StringBuilder pathToDest = new StringBuilder(); + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + int i = 0; + while (i < pathToStart.length() && i < pathToDest.length() + && pathToStart.charAt(i) == pathToDest.charAt(i)) { + ++i; } - return new String(path, answerIdx, destLevel - answerIdx); + return "U".repeat(pathToStart.length() - i) + pathToDest.substring(i); } - private int findPaths(TreeNode node, int strtVal, int destVal, int level) { + private boolean dfs(TreeNode node, int x, StringBuilder path) { if (node == null) { - return 0; - } - int result = 0; - if (node.val == strtVal) { - strtLevel = level; - result = 1; - } else if (node.val == destVal) { - destLevel = level; - result = 1; - } - int leftFound = 0; - int rightFound = 0; - if (comnLevel < 0) { - if (destLevel < 0) { - path[level] = 'L'; - } - leftFound = findPaths(node.left, strtVal, destVal, level + 1); - rightFound = 0; - if (comnLevel < 0) { - if (destLevel < 0) { - path[level] = 'R'; - } - rightFound = findPaths(node.right, strtVal, destVal, level + 1); - } - } - if (comnLevel < 0 && leftFound + rightFound + result == 2) { - comnLevel = level; - } - return result | leftFound | rightFound; + return false; + } + if (node.val == x) { + return true; + } + path.append('L'); + if (dfs(node.left, x, path)) { + return true; + } + path.setCharAt(path.length() - 1, 'R'); + if (dfs(node.right, x, path)) { + return true; + } + path.deleteCharAt(path.length() - 1); + return false; } } ``` - +#### C++ - +```cpp +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + string getDirections(TreeNode* root, int startValue, int destValue) { + string pathToStart, pathToDest; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + int i = 0; + while (i < pathToStart.size() && i < pathToDest.size() && pathToStart[i] == pathToDest[i]) { + i++; + } + return string(pathToStart.size() - i, 'U') + pathToDest.substr(i); + } - +private: + bool dfs(TreeNode* node, int x, string& path) { + if (node == nullptr) { + return false; + } + if (node->val == x) { + return true; + } + path.push_back('L'); + if (dfs(node->left, x, path)) { + return true; + } + path.back() = 'R'; + if (dfs(node->right, x, path)) { + return true; + } + path.pop_back(); + return false; + } +}; +``` -#### Solution 3: LCA + DFS (Optimized) +#### Go - +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func getDirections(root *TreeNode, startValue int, destValue int) string { + var dfs func(node *TreeNode, x int, path *[]byte) bool + dfs = func(node *TreeNode, x int, path *[]byte) bool { + if node == nil { + return false + } + if node.Val == x { + return true + } + *path = append(*path, 'L') + if dfs(node.Left, x, path) { + return true + } + (*path)[len(*path)-1] = 'R' + if dfs(node.Right, x, path) { + return true + } + *path = (*path)[:len(*path)-1] + return false + } + + pathToStart := []byte{} + pathToDest := []byte{} + dfs(root, startValue, &pathToStart) + dfs(root, destValue, &pathToDest) + i := 0 + for i < len(pathToStart) && i < len(pathToDest) && pathToStart[i] == pathToDest[i] { + i++ + } + return string(bytes.Repeat([]byte{'U'}, len(pathToStart)-i)) + string(pathToDest[i:]) +} +``` #### TypeScript @@ -505,35 +606,84 @@ class Solution { * } * } */ -export function getDirections(root: TreeNode | null, start: number, dest: number): string { - const dfs = (node: TreeNode | null, x: number, path: string[] = []): boolean => { - if (!node) return false; - if (node.val === x) return true; +function getDirections(root: TreeNode | null, startValue: number, destValue: number): string { + const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => { + if (node === null) { + return false; + } + if (node.val === x) { + return true; + } path.push('L'); - if (dfs(node.left, x, path)) return true; - + if (dfs(node.left, x, path)) { + return true; + } path[path.length - 1] = 'R'; - if (dfs(node.right, x, path)) return true; + if (dfs(node.right, x, path)) { + return true; + } path.pop(); - return false; }; + const pathToStart: string[] = []; + const pathToDest: string[] = []; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + let i = 0; + while (pathToStart[i] === pathToDest[i]) { + ++i; + } + return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join(''); +} +``` - const startPath: string[] = []; - const destPath: string[] = []; - dfs(root, start, startPath); - dfs(root, dest, destPath); +#### JavaScript +```js +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} startValue + * @param {number} destValue + * @return {string} + */ +var getDirections = function (root, startValue, destValue) { + const dfs = (node, x, path) => { + if (node === null) { + return false; + } + if (node.val === x) { + return true; + } + path.push('L'); + if (dfs(node.left, x, path)) { + return true; + } + path[path.length - 1] = 'R'; + if (dfs(node.right, x, path)) { + return true; + } + path.pop(); + return false; + }; + const pathToStart = []; + const pathToDest = []; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); let i = 0; - while (startPath[i] === destPath[i]) i++; - - return ( - Array(startPath.length - i) - .fill('U') - .join('') + destPath.slice(i).join('') - ); -} + while (pathToStart[i] === pathToDest[i]) { + ++i; + } + return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join(''); +}; ``` diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md index 94082f2496444..41a9811d4e980 100644 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md @@ -403,87 +403,188 @@ var getDirections = function (root, startValue, destValue) { -#### Solution 2: DFS +### Solution 2: Lowest Common Ancestor + DFS (Optimized) + +We can start from $\textit{root}$, find the paths to $\textit{startValue}$ and $\textit{destValue}$, denoted as $\textit{pathToStart}$ and $\textit{pathToDest}$, respectively. Then, remove the longest common prefix of $\textit{pathToStart}$ and $\textit{pathToDest}$. At this point, the length of $\textit{pathToStart}$ is the number of $\textit{U}$s in the answer, and the path of $\textit{pathToDest}$ is the path in the answer. We just need to concatenate these two paths. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree. +#### Python3 + +```python +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right + + +class Solution: + def getDirections( + self, root: Optional[TreeNode], startValue: int, destValue: int + ) -> str: + def dfs(node: Optional[TreeNode], x: int, path: List[str]): + if node is None: + return False + if node.val == x: + return True + path.append("L") + if dfs(node.left, x, path): + return True + path[-1] = "R" + if dfs(node.right, x, path): + return True + path.pop() + return False + + path_to_start = [] + path_to_dest = [] + + dfs(root, startValue, path_to_start) + dfs(root, destValue, path_to_dest) + i = 0 + while ( + i < len(path_to_start) + and i < len(path_to_dest) + and path_to_start[i] == path_to_dest[i] + ): + i += 1 + return "U" * (len(path_to_start) - i) + "".join(path_to_dest[i:]) +``` + #### Java ```java -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode() {} - * TreeNode(int val) { this.val = val; } - * TreeNode(int val, TreeNode left, TreeNode right) { - * this.val = val; - * this.left = left; - * this.right = right; - * } - * } - */ class Solution { - static byte[] path = new byte[200_001]; - int strtLevel = -1; - int destLevel = -1; - int comnLevel = -1; - public String getDirections(TreeNode root, int startValue, int destValue) { - findPaths(root, startValue, destValue, 100_000); - int answerIdx = comnLevel; - for (int i = strtLevel; i > comnLevel; i--) { - path[--answerIdx] = 'U'; + StringBuilder pathToStart = new StringBuilder(); + StringBuilder pathToDest = new StringBuilder(); + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + int i = 0; + while (i < pathToStart.length() && i < pathToDest.length() + && pathToStart.charAt(i) == pathToDest.charAt(i)) { + ++i; } - return new String(path, answerIdx, destLevel - answerIdx); + return "U".repeat(pathToStart.length() - i) + pathToDest.substring(i); } - private int findPaths(TreeNode node, int strtVal, int destVal, int level) { + private boolean dfs(TreeNode node, int x, StringBuilder path) { if (node == null) { - return 0; - } - int result = 0; - if (node.val == strtVal) { - strtLevel = level; - result = 1; - } else if (node.val == destVal) { - destLevel = level; - result = 1; - } - int leftFound = 0; - int rightFound = 0; - if (comnLevel < 0) { - if (destLevel < 0) { - path[level] = 'L'; - } - leftFound = findPaths(node.left, strtVal, destVal, level + 1); - rightFound = 0; - if (comnLevel < 0) { - if (destLevel < 0) { - path[level] = 'R'; - } - rightFound = findPaths(node.right, strtVal, destVal, level + 1); - } - } - if (comnLevel < 0 && leftFound + rightFound + result == 2) { - comnLevel = level; - } - return result | leftFound | rightFound; + return false; + } + if (node.val == x) { + return true; + } + path.append('L'); + if (dfs(node.left, x, path)) { + return true; + } + path.setCharAt(path.length() - 1, 'R'); + if (dfs(node.right, x, path)) { + return true; + } + path.deleteCharAt(path.length() - 1); + return false; } } ``` - +#### C++ - +```cpp +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + string getDirections(TreeNode* root, int startValue, int destValue) { + string pathToStart, pathToDest; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + int i = 0; + while (i < pathToStart.size() && i < pathToDest.size() && pathToStart[i] == pathToDest[i]) { + i++; + } + return string(pathToStart.size() - i, 'U') + pathToDest.substr(i); + } - +private: + bool dfs(TreeNode* node, int x, string& path) { + if (node == nullptr) { + return false; + } + if (node->val == x) { + return true; + } + path.push_back('L'); + if (dfs(node->left, x, path)) { + return true; + } + path.back() = 'R'; + if (dfs(node->right, x, path)) { + return true; + } + path.pop_back(); + return false; + } +}; +``` -#### Solution 3: LCA + DFS (Optimized) +#### Go - +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func getDirections(root *TreeNode, startValue int, destValue int) string { + var dfs func(node *TreeNode, x int, path *[]byte) bool + dfs = func(node *TreeNode, x int, path *[]byte) bool { + if node == nil { + return false + } + if node.Val == x { + return true + } + *path = append(*path, 'L') + if dfs(node.Left, x, path) { + return true + } + (*path)[len(*path)-1] = 'R' + if dfs(node.Right, x, path) { + return true + } + *path = (*path)[:len(*path)-1] + return false + } + + pathToStart := []byte{} + pathToDest := []byte{} + dfs(root, startValue, &pathToStart) + dfs(root, destValue, &pathToDest) + i := 0 + for i < len(pathToStart) && i < len(pathToDest) && pathToStart[i] == pathToDest[i] { + i++ + } + return string(bytes.Repeat([]byte{'U'}, len(pathToStart)-i)) + string(pathToDest[i:]) +} +``` #### TypeScript @@ -501,35 +602,84 @@ class Solution { * } * } */ -export function getDirections(root: TreeNode | null, start: number, dest: number): string { - const dfs = (node: TreeNode | null, x: number, path: string[] = []): boolean => { - if (!node) return false; - if (node.val === x) return true; +function getDirections(root: TreeNode | null, startValue: number, destValue: number): string { + const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => { + if (node === null) { + return false; + } + if (node.val === x) { + return true; + } path.push('L'); - if (dfs(node.left, x, path)) return true; - + if (dfs(node.left, x, path)) { + return true; + } path[path.length - 1] = 'R'; - if (dfs(node.right, x, path)) return true; + if (dfs(node.right, x, path)) { + return true; + } path.pop(); - return false; }; + const pathToStart: string[] = []; + const pathToDest: string[] = []; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + let i = 0; + while (pathToStart[i] === pathToDest[i]) { + ++i; + } + return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join(''); +} +``` - const startPath: string[] = []; - const destPath: string[] = []; - dfs(root, start, startPath); - dfs(root, dest, destPath); +#### JavaScript +```js +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} startValue + * @param {number} destValue + * @return {string} + */ +var getDirections = function (root, startValue, destValue) { + const dfs = (node, x, path) => { + if (node === null) { + return false; + } + if (node.val === x) { + return true; + } + path.push('L'); + if (dfs(node.left, x, path)) { + return true; + } + path[path.length - 1] = 'R'; + if (dfs(node.right, x, path)) { + return true; + } + path.pop(); + return false; + }; + const pathToStart = []; + const pathToDest = []; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); let i = 0; - while (startPath[i] === destPath[i]) i++; - - return ( - Array(startPath.length - i) - .fill('U') - .join('') + destPath.slice(i).join('') - ); -} + while (pathToStart[i] === pathToDest[i]) { + ++i; + } + return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join(''); +}; ``` diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.cpp b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.cpp new file mode 100644 index 0000000000000..a41bdeceac750 --- /dev/null +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.cpp @@ -0,0 +1,44 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + string getDirections(TreeNode* root, int startValue, int destValue) { + string pathToStart, pathToDest; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + int i = 0; + while (i < pathToStart.size() && i < pathToDest.size() && pathToStart[i] == pathToDest[i]) { + i++; + } + return string(pathToStart.size() - i, 'U') + pathToDest.substr(i); + } + +private: + bool dfs(TreeNode* node, int x, string& path) { + if (node == nullptr) { + return false; + } + if (node->val == x) { + return true; + } + path.push_back('L'); + if (dfs(node->left, x, path)) { + return true; + } + path.back() = 'R'; + if (dfs(node->right, x, path)) { + return true; + } + path.pop_back(); + return false; + } +}; diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.go b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.go new file mode 100644 index 0000000000000..9bebac83bd57d --- /dev/null +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.go @@ -0,0 +1,39 @@ +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func getDirections(root *TreeNode, startValue int, destValue int) string { + var dfs func(node *TreeNode, x int, path *[]byte) bool + dfs = func(node *TreeNode, x int, path *[]byte) bool { + if node == nil { + return false + } + if node.Val == x { + return true + } + *path = append(*path, 'L') + if dfs(node.Left, x, path) { + return true + } + (*path)[len(*path)-1] = 'R' + if dfs(node.Right, x, path) { + return true + } + *path = (*path)[:len(*path)-1] + return false + } + + pathToStart := []byte{} + pathToDest := []byte{} + dfs(root, startValue, &pathToStart) + dfs(root, destValue, &pathToDest) + i := 0 + for i < len(pathToStart) && i < len(pathToDest) && pathToStart[i] == pathToDest[i] { + i++ + } + return string(bytes.Repeat([]byte{'U'}, len(pathToStart)-i)) + string(pathToDest[i:]) +} diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.java b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.java index 4c16d80a5f41a..cc9de2feb49f5 100644 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.java +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.java @@ -1,63 +1,33 @@ -/** - * Definition for a binary tree node. - * public class TreeNode { - * int val; - * TreeNode left; - * TreeNode right; - * TreeNode() {} - * TreeNode(int val) { this.val = val; } - * TreeNode(int val, TreeNode left, TreeNode right) { - * this.val = val; - * this.left = left; - * this.right = right; - * } - * } - */ class Solution { - static byte[] path = new byte[200_001]; - int strtLevel = -1; - int destLevel = -1; - int comnLevel = -1; - public String getDirections(TreeNode root, int startValue, int destValue) { - findPaths(root, startValue, destValue, 100_000); - int answerIdx = comnLevel; - for (int i = strtLevel; i > comnLevel; i--) { - path[--answerIdx] = 'U'; + StringBuilder pathToStart = new StringBuilder(); + StringBuilder pathToDest = new StringBuilder(); + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + int i = 0; + while (i < pathToStart.length() && i < pathToDest.length() + && pathToStart.charAt(i) == pathToDest.charAt(i)) { + ++i; } - return new String(path, answerIdx, destLevel - answerIdx); + return "U".repeat(pathToStart.length() - i) + pathToDest.substring(i); } - private int findPaths(TreeNode node, int strtVal, int destVal, int level) { + private boolean dfs(TreeNode node, int x, StringBuilder path) { if (node == null) { - return 0; + return false; } - int result = 0; - if (node.val == strtVal) { - strtLevel = level; - result = 1; - } else if (node.val == destVal) { - destLevel = level; - result = 1; + if (node.val == x) { + return true; } - int leftFound = 0; - int rightFound = 0; - if (comnLevel < 0) { - if (destLevel < 0) { - path[level] = 'L'; - } - leftFound = findPaths(node.left, strtVal, destVal, level + 1); - rightFound = 0; - if (comnLevel < 0) { - if (destLevel < 0) { - path[level] = 'R'; - } - rightFound = findPaths(node.right, strtVal, destVal, level + 1); - } + path.append('L'); + if (dfs(node.left, x, path)) { + return true; } - if (comnLevel < 0 && leftFound + rightFound + result == 2) { - comnLevel = level; + path.setCharAt(path.length() - 1, 'R'); + if (dfs(node.right, x, path)) { + return true; } - return result | leftFound | rightFound; + path.deleteCharAt(path.length() - 1); + return false; } } diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.js b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.js new file mode 100644 index 0000000000000..4a1ff8a30ec21 --- /dev/null +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.js @@ -0,0 +1,43 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} startValue + * @param {number} destValue + * @return {string} + */ +var getDirections = function (root, startValue, destValue) { + const dfs = (node, x, path) => { + if (node === null) { + return false; + } + if (node.val === x) { + return true; + } + path.push('L'); + if (dfs(node.left, x, path)) { + return true; + } + path[path.length - 1] = 'R'; + if (dfs(node.right, x, path)) { + return true; + } + path.pop(); + return false; + }; + const pathToStart = []; + const pathToDest = []; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + let i = 0; + while (pathToStart[i] === pathToDest[i]) { + ++i; + } + return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join(''); +}; diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.py b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.py new file mode 100644 index 0000000000000..0e75b115b0d77 --- /dev/null +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.py @@ -0,0 +1,39 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right + + +class Solution: + def getDirections( + self, root: Optional[TreeNode], startValue: int, destValue: int + ) -> str: + def dfs(node: Optional[TreeNode], x: int, path: List[str]): + if node is None: + return False + if node.val == x: + return True + path.append("L") + if dfs(node.left, x, path): + return True + path[-1] = "R" + if dfs(node.right, x, path): + return True + path.pop() + return False + + path_to_start = [] + path_to_dest = [] + + dfs(root, startValue, path_to_start) + dfs(root, destValue, path_to_dest) + i = 0 + while ( + i < len(path_to_start) + and i < len(path_to_dest) + and path_to_start[i] == path_to_dest[i] + ): + i += 1 + return "U" * (len(path_to_start) - i) + "".join(path_to_dest[i:]) diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.ts b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.ts new file mode 100644 index 0000000000000..c9c209c5dbd30 --- /dev/null +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution2.ts @@ -0,0 +1,43 @@ +/** + * 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 getDirections(root: TreeNode | null, startValue: number, destValue: number): string { + const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => { + if (node === null) { + return false; + } + if (node.val === x) { + return true; + } + path.push('L'); + if (dfs(node.left, x, path)) { + return true; + } + path[path.length - 1] = 'R'; + if (dfs(node.right, x, path)) { + return true; + } + path.pop(); + return false; + }; + const pathToStart: string[] = []; + const pathToDest: string[] = []; + dfs(root, startValue, pathToStart); + dfs(root, destValue, pathToDest); + let i = 0; + while (pathToStart[i] === pathToDest[i]) { + ++i; + } + return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join(''); +} diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution3.js b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution3.js deleted file mode 100644 index bdf29e35a2190..0000000000000 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution3.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Definition for a binary tree node. - * function TreeNode(val, left, right) { - * this.val = (val===undefined ? 0 : val) - * this.left = (left===undefined ? null : left) - * this.right = (right===undefined ? null : right) - * } - */ -/** - * @param {TreeNode} root - * @param {number} startValue - * @param {number} destValue - * @return {string} - */ -var getDirections = function (root, start, dest) { - const dfs = (node, x, path = []) => { - if (!node) return false; - if (node.val === x) return true; - - path.push('L'); - if (dfs(node.left, x, path)) return true; - - path[path.length - 1] = 'R'; - if (dfs(node.right, x, path)) return true; - path.pop(); - - return false; - }; - - const startPath = []; - const destPath = []; - dfs(root, start, startPath); - dfs(root, dest, destPath); - - let i = 0; - while (startPath[i] === destPath[i]) i++; - - return ( - Array(startPath.length - i) - .fill('U') - .join('') + destPath.slice(i).join('') - ); -}; diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution3.ts b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution3.ts deleted file mode 100644 index 6681dd29c13b2..0000000000000 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution3.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * 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) - * } - * } - */ -export function getDirections(root: TreeNode | null, start: number, dest: number): string { - const dfs = (node: TreeNode | null, x: number, path: string[] = []): boolean => { - if (!node) return false; - if (node.val === x) return true; - - path.push('L'); - if (dfs(node.left, x, path)) return true; - - path[path.length - 1] = 'R'; - if (dfs(node.right, x, path)) return true; - path.pop(); - - return false; - }; - - const startPath: string[] = []; - const destPath: string[] = []; - dfs(root, start, startPath); - dfs(root, dest, destPath); - - let i = 0; - while (startPath[i] === destPath[i]) i++; - - return ( - Array(startPath.length - i) - .fill('U') - .join('') + destPath.slice(i).join('') - ); -}