@@ -407,87 +407,188 @@ var getDirections = function (root, startValue, destValue) {
407
407
408
408
<!-- solution:start -->
409
409
410
- #### 方法二:DFS
410
+ ### 方法二:最近公共祖先 + DFS(优化)
411
+
412
+ 我们可以从 $\t extit{root}$ 出发,找到 $\t extit{startValue}$ 和 $\t extit{destValue}$ 的路径,记为 $\t extit{pathToStart}$ 和 $\t extit{pathToDest}$,然后去除 $\t extit{pathToStart}$ 和 $\t extit{pathToDest}$ 的最长公共前缀,此时 $\t extit{pathToStart}$ 的路径长度就是答案中 $\t extit{U}$ 的个数,而 $\t extit{pathToDest}$ 的路径就是答案中的路径,我们只需要将这两个路径拼接起来即可。
413
+
414
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉树的节点数。
411
415
412
416
<!-- tabs:start -->
413
417
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
+
414
462
#### Java
415
463
416
464
` ` ` 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
- */
432
465
class Solution {
433
- static byte[] path = new byte [200_001 ];
434
- int strtLevel = - 1 ;
435
- int destLevel = - 1 ;
436
- int comnLevel = - 1 ;
437
-
438
466
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;
443
475
}
444
- return new String (path, answerIdx, destLevel - answerIdx );
476
+ return " U " . repeat ( pathToStart . length () - i) + pathToDest . substring (i );
445
477
}
446
478
447
- private int findPaths (TreeNode node , int strtVal , int destVal , int level ) {
479
+ private boolean dfs (TreeNode node , int x , StringBuilder path ) {
448
480
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 ;
478
496
}
479
497
}
480
498
` ` `
481
499
482
- <!-- tabs:end -->
500
+ #### C++
483
501
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
+ }
485
526
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
+ ` ` `
487
548
488
- #### Solution 3: LCA + DFS (Optimized)
549
+ #### Go
489
550
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
+ ` ` `
491
592
492
593
#### TypeScript
493
594
@@ -505,35 +606,84 @@ class Solution {
505
606
* }
506
607
* }
507
608
*/
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 ;
512
609
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
+ }
513
618
path .push (' L' );
514
- if (dfs (node .left , x, path)) return true ;
515
-
619
+ if (dfs (node .left , x, path)) {
620
+ return true ;
621
+ }
516
622
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
+ }
518
626
path .pop ();
519
-
520
627
return false ;
521
628
};
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
+ ` ` `
522
640
523
- const startPath: string [] = [];
524
- const destPath: string [] = [];
525
- dfs (root, start, startPath);
526
- dfs (root, dest, destPath);
641
+ #### JavaScript
527
642
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);
528
681
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
+ };
537
687
` ` `
538
688
539
689
<!-- tabs:end -->
0 commit comments