Skip to content

Commit bd65973

Browse files
authored
feat: add solutions to lc problem: No.2096 (#3303)
No.2096.Step-By-Step Directions From a Binary Tree Node to Another
1 parent c5962ae commit bd65973

File tree

10 files changed

+691
-298
lines changed

10 files changed

+691
-298
lines changed

Diff for: solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md

+231-81
Original file line numberDiff line numberDiff line change
@@ -407,87 +407,188 @@ var getDirections = function (root, startValue, destValue) {
407407
408408
<!-- solution:start -->
409409
410-
#### 方法二:DFS
410+
### 方法二:最近公共祖先 + DFS(优化)
411+
412+
我们可以从 $\textit{root}$ 出发,找到 $\textit{startValue}$ 和 $\textit{destValue}$ 的路径,记为 $\textit{pathToStart}$ 和 $\textit{pathToDest}$,然后去除 $\textit{pathToStart}$ 和 $\textit{pathToDest}$ 的最长公共前缀,此时 $\textit{pathToStart}$ 的路径长度就是答案中 $\textit{U}$ 的个数,而 $\textit{pathToDest}$ 的路径就是答案中的路径,我们只需要将这两个路径拼接起来即可。
413+
414+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树的节点数。
411415
412416
<!-- tabs:start -->
413417
418+
#### Python3
419+
420+
```python
421+
# Definition for a binary tree node.
422+
# class TreeNode:
423+
# def __init__(self, val=0, left=None, right=None):
424+
# self.val = val
425+
# self.left = left
426+
# self.right = right
427+
428+
429+
class Solution:
430+
def getDirections(
431+
self, root: Optional[TreeNode], startValue: int, destValue: int
432+
) -> str:
433+
def dfs(node: Optional[TreeNode], x: int, path: List[str]):
434+
if node is None:
435+
return False
436+
if node.val == x:
437+
return True
438+
path.append("L")
439+
if dfs(node.left, x, path):
440+
return True
441+
path[-1] = "R"
442+
if dfs(node.right, x, path):
443+
return True
444+
path.pop()
445+
return False
446+
447+
path_to_start = []
448+
path_to_dest = []
449+
450+
dfs(root, startValue, path_to_start)
451+
dfs(root, destValue, path_to_dest)
452+
i = 0
453+
while (
454+
i < len(path_to_start)
455+
and i < len(path_to_dest)
456+
and path_to_start[i] == path_to_dest[i]
457+
):
458+
i += 1
459+
return "U" * (len(path_to_start) - i) + "".join(path_to_dest[i:])
460+
```
461+
414462
#### Java
415463
416464
```java
417-
/**
418-
* Definition for a binary tree node.
419-
* public class TreeNode {
420-
* int val;
421-
* TreeNode left;
422-
* TreeNode right;
423-
* TreeNode() {}
424-
* TreeNode(int val) { this.val = val; }
425-
* TreeNode(int val, TreeNode left, TreeNode right) {
426-
* this.val = val;
427-
* this.left = left;
428-
* this.right = right;
429-
* }
430-
* }
431-
*/
432465
class Solution {
433-
static byte[] path = new byte[200_001];
434-
int strtLevel = -1;
435-
int destLevel = -1;
436-
int comnLevel = -1;
437-
438466
public String getDirections(TreeNode root, int startValue, int destValue) {
439-
findPaths(root, startValue, destValue, 100_000);
440-
int answerIdx = comnLevel;
441-
for (int i = strtLevel; i > comnLevel; i--) {
442-
path[--answerIdx] = 'U';
467+
StringBuilder pathToStart = new StringBuilder();
468+
StringBuilder pathToDest = new StringBuilder();
469+
dfs(root, startValue, pathToStart);
470+
dfs(root, destValue, pathToDest);
471+
int i = 0;
472+
while (i < pathToStart.length() && i < pathToDest.length()
473+
&& pathToStart.charAt(i) == pathToDest.charAt(i)) {
474+
++i;
443475
}
444-
return new String(path, answerIdx, destLevel - answerIdx);
476+
return "U".repeat(pathToStart.length() - i) + pathToDest.substring(i);
445477
}
446478

447-
private int findPaths(TreeNode node, int strtVal, int destVal, int level) {
479+
private boolean dfs(TreeNode node, int x, StringBuilder path) {
448480
if (node == null) {
449-
return 0;
450-
}
451-
int result = 0;
452-
if (node.val == strtVal) {
453-
strtLevel = level;
454-
result = 1;
455-
} else if (node.val == destVal) {
456-
destLevel = level;
457-
result = 1;
458-
}
459-
int leftFound = 0;
460-
int rightFound = 0;
461-
if (comnLevel < 0) {
462-
if (destLevel < 0) {
463-
path[level] = 'L';
464-
}
465-
leftFound = findPaths(node.left, strtVal, destVal, level + 1);
466-
rightFound = 0;
467-
if (comnLevel < 0) {
468-
if (destLevel < 0) {
469-
path[level] = 'R';
470-
}
471-
rightFound = findPaths(node.right, strtVal, destVal, level + 1);
472-
}
473-
}
474-
if (comnLevel < 0 && leftFound + rightFound + result == 2) {
475-
comnLevel = level;
476-
}
477-
return result | leftFound | rightFound;
481+
return false;
482+
}
483+
if (node.val == x) {
484+
return true;
485+
}
486+
path.append('L');
487+
if (dfs(node.left, x, path)) {
488+
return true;
489+
}
490+
path.setCharAt(path.length() - 1, 'R');
491+
if (dfs(node.right, x, path)) {
492+
return true;
493+
}
494+
path.deleteCharAt(path.length() - 1);
495+
return false;
478496
}
479497
}
480498
```
481499
482-
<!-- tabs:end -->
500+
#### C++
483501
484-
<!-- solution:end -->
502+
```cpp
503+
/**
504+
* Definition for a binary tree node.
505+
* struct TreeNode {
506+
* int val;
507+
* TreeNode *left;
508+
* TreeNode *right;
509+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
510+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
511+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
512+
* };
513+
*/
514+
class Solution {
515+
public:
516+
string getDirections(TreeNode* root, int startValue, int destValue) {
517+
string pathToStart, pathToDest;
518+
dfs(root, startValue, pathToStart);
519+
dfs(root, destValue, pathToDest);
520+
int i = 0;
521+
while (i < pathToStart.size() && i < pathToDest.size() && pathToStart[i] == pathToDest[i]) {
522+
i++;
523+
}
524+
return string(pathToStart.size() - i, 'U') + pathToDest.substr(i);
525+
}
485526

486-
<!-- solution:start -->
527+
private:
528+
bool dfs(TreeNode* node, int x, string& path) {
529+
if (node == nullptr) {
530+
return false;
531+
}
532+
if (node->val == x) {
533+
return true;
534+
}
535+
path.push_back('L');
536+
if (dfs(node->left, x, path)) {
537+
return true;
538+
}
539+
path.back() = 'R';
540+
if (dfs(node->right, x, path)) {
541+
return true;
542+
}
543+
path.pop_back();
544+
return false;
545+
}
546+
};
547+
```
487548
488-
#### Solution 3: LCA + DFS (Optimized)
549+
#### Go
489550
490-
<!-- tabs:start -->
551+
```go
552+
/**
553+
* Definition for a binary tree node.
554+
* type TreeNode struct {
555+
* Val int
556+
* Left *TreeNode
557+
* Right *TreeNode
558+
* }
559+
*/
560+
func getDirections(root *TreeNode, startValue int, destValue int) string {
561+
var dfs func(node *TreeNode, x int, path *[]byte) bool
562+
dfs = func(node *TreeNode, x int, path *[]byte) bool {
563+
if node == nil {
564+
return false
565+
}
566+
if node.Val == x {
567+
return true
568+
}
569+
*path = append(*path, 'L')
570+
if dfs(node.Left, x, path) {
571+
return true
572+
}
573+
(*path)[len(*path)-1] = 'R'
574+
if dfs(node.Right, x, path) {
575+
return true
576+
}
577+
*path = (*path)[:len(*path)-1]
578+
return false
579+
}
580+
581+
pathToStart := []byte{}
582+
pathToDest := []byte{}
583+
dfs(root, startValue, &pathToStart)
584+
dfs(root, destValue, &pathToDest)
585+
i := 0
586+
for i < len(pathToStart) && i < len(pathToDest) && pathToStart[i] == pathToDest[i] {
587+
i++
588+
}
589+
return string(bytes.Repeat([]byte{'U'}, len(pathToStart)-i)) + string(pathToDest[i:])
590+
}
591+
```
491592
492593
#### TypeScript
493594
@@ -505,35 +606,84 @@ class Solution {
505606
* }
506607
* }
507608
*/
508-
export function getDirections(root: TreeNode | null, start: number, dest: number): string {
509-
const dfs = (node: TreeNode | null, x: number, path: string[] = []): boolean => {
510-
if (!node) return false;
511-
if (node.val === x) return true;
512609

610+
function getDirections(root: TreeNode | null, startValue: number, destValue: number): string {
611+
const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => {
612+
if (node === null) {
613+
return false;
614+
}
615+
if (node.val === x) {
616+
return true;
617+
}
513618
path.push('L');
514-
if (dfs(node.left, x, path)) return true;
515-
619+
if (dfs(node.left, x, path)) {
620+
return true;
621+
}
516622
path[path.length - 1] = 'R';
517-
if (dfs(node.right, x, path)) return true;
623+
if (dfs(node.right, x, path)) {
624+
return true;
625+
}
518626
path.pop();
519-
520627
return false;
521628
};
629+
const pathToStart: string[] = [];
630+
const pathToDest: string[] = [];
631+
dfs(root, startValue, pathToStart);
632+
dfs(root, destValue, pathToDest);
633+
let i = 0;
634+
while (pathToStart[i] === pathToDest[i]) {
635+
++i;
636+
}
637+
return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join('');
638+
}
639+
```
522640
523-
const startPath: string[] = [];
524-
const destPath: string[] = [];
525-
dfs(root, start, startPath);
526-
dfs(root, dest, destPath);
641+
#### JavaScript
527642
643+
```js
644+
/**
645+
* Definition for a binary tree node.
646+
* function TreeNode(val, left, right) {
647+
* this.val = (val===undefined ? 0 : val)
648+
* this.left = (left===undefined ? null : left)
649+
* this.right = (right===undefined ? null : right)
650+
* }
651+
*/
652+
/**
653+
* @param {TreeNode} root
654+
* @param {number} startValue
655+
* @param {number} destValue
656+
* @return {string}
657+
*/
658+
var getDirections = function (root, startValue, destValue) {
659+
const dfs = (node, x, path) => {
660+
if (node === null) {
661+
return false;
662+
}
663+
if (node.val === x) {
664+
return true;
665+
}
666+
path.push('L');
667+
if (dfs(node.left, x, path)) {
668+
return true;
669+
}
670+
path[path.length - 1] = 'R';
671+
if (dfs(node.right, x, path)) {
672+
return true;
673+
}
674+
path.pop();
675+
return false;
676+
};
677+
const pathToStart = [];
678+
const pathToDest = [];
679+
dfs(root, startValue, pathToStart);
680+
dfs(root, destValue, pathToDest);
528681
let i = 0;
529-
while (startPath[i] === destPath[i]) i++;
530-
531-
return (
532-
Array(startPath.length - i)
533-
.fill('U')
534-
.join('') + destPath.slice(i).join('')
535-
);
536-
}
682+
while (pathToStart[i] === pathToDest[i]) {
683+
++i;
684+
}
685+
return 'U'.repeat(pathToStart.length - i) + pathToDest.slice(i).join('');
686+
};
537687
```
538688
539689
<!-- tabs:end -->

0 commit comments

Comments
 (0)