@@ -407,87 +407,187 @@ 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 () && pathToStart .charAt (i) == pathToDest .charAt (i)) {
473
+ ++ i;
443
474
}
444
- return new String (path, answerIdx, destLevel - answerIdx );
475
+ return " U " . repeat ( pathToStart . length () - i) + pathToDest . substring (i );
445
476
}
446
477
447
- private int findPaths (TreeNode node , int strtVal , int destVal , int level ) {
478
+ private boolean dfs (TreeNode node , int x , StringBuilder path ) {
448
479
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;
480
+ return false ;
481
+ }
482
+ if (node .val == x) {
483
+ return true ;
484
+ }
485
+ path .append (' L' );
486
+ if (dfs (node .left , x, path)) {
487
+ return true ;
488
+ }
489
+ path .setCharAt (path .length () - 1 , ' R' );
490
+ if (dfs (node .right , x, path)) {
491
+ return true ;
492
+ }
493
+ path .deleteCharAt (path .length () - 1 );
494
+ return false ;
478
495
}
479
496
}
480
497
` ` `
481
498
482
- <!-- tabs:end -->
499
+ #### C++
483
500
484
- <!-- solution:end -->
501
+ ` ` ` cpp
502
+ /**
503
+ * Definition for a binary tree node.
504
+ * struct TreeNode {
505
+ * int val;
506
+ * TreeNode *left;
507
+ * TreeNode *right;
508
+ * TreeNode() : val(0), left(nullptr), right(nullptr) {}
509
+ * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
510
+ * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
511
+ * };
512
+ */
513
+ class Solution {
514
+ public:
515
+ string getDirections (TreeNode * root , int startValue , int destValue ) {
516
+ string pathToStart, pathToDest;
517
+ dfs (root, startValue, pathToStart);
518
+ dfs (root, destValue, pathToDest);
519
+ int i = 0 ;
520
+ while (i < pathToStart .size () && i < pathToDest .size () && pathToStart[i] == pathToDest[i]) {
521
+ i++ ;
522
+ }
523
+ return string (pathToStart .size () - i, ' U' ) + pathToDest .substr (i);
524
+ }
485
525
486
- <!-- solution:start -->
526
+ private:
527
+ bool dfs (TreeNode * node , int x , string & path ) {
528
+ if (node == nullptr) {
529
+ return false ;
530
+ }
531
+ if (node- > val == x) {
532
+ return true ;
533
+ }
534
+ path .push_back (' L' );
535
+ if (dfs (node- > left, x, path)) {
536
+ return true ;
537
+ }
538
+ path .back () = ' R' ;
539
+ if (dfs (node- > right, x, path)) {
540
+ return true ;
541
+ }
542
+ path .pop_back ();
543
+ return false ;
544
+ }
545
+ };
546
+ ` ` `
487
547
488
- #### Solution 3: LCA + DFS (Optimized)
548
+ #### Go
489
549
490
- <!-- tabs:start -->
550
+ ` ` ` go
551
+ /**
552
+ * Definition for a binary tree node.
553
+ * type TreeNode struct {
554
+ * Val int
555
+ * Left *TreeNode
556
+ * Right *TreeNode
557
+ * }
558
+ */
559
+ func getDirections (root * TreeNode, startValue int, destValue int) string {
560
+ var dfs func (node * TreeNode, x int, path * []byte) bool
561
+ dfs = func (node * TreeNode, x int, path * []byte) bool {
562
+ if node == nil {
563
+ return false
564
+ }
565
+ if node .Val == x {
566
+ return true
567
+ }
568
+ * path = append (* path, ' L' )
569
+ if dfs (node .Left , x , path ) {
570
+ return true
571
+ }
572
+ (* path)[len (* path)- 1 ] = ' R'
573
+ if dfs (node .Right , x , path ) {
574
+ return true
575
+ }
576
+ * path = (* path)[: len (* path)- 1 ]
577
+ return false
578
+ }
579
+
580
+ pathToStart := []byte{}
581
+ pathToDest := []byte{}
582
+ dfs (root, startValue, & pathToStart)
583
+ dfs (root, destValue, & pathToDest)
584
+ i := 0
585
+ for i < len (pathToStart) && i < len (pathToDest) && pathToStart[i] == pathToDest[i] {
586
+ i++
587
+ }
588
+ return string (bytes .Repeat ([]byte{' U' }, len (pathToStart)- i)) + string (pathToDest[i: ])
589
+ }
590
+ ` ` `
491
591
492
592
#### TypeScript
493
593
@@ -505,35 +605,84 @@ class Solution {
505
605
* }
506
606
* }
507
607
*/
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
608
609
+ function getDirections (root : TreeNode | null , startValue : number , destValue : number ): string {
610
+ const dfs = (node: TreeNode | null , x: number, path: string[]): boolean => {
611
+ if (node === null ) {
612
+ return false ;
613
+ }
614
+ if (node .val === x) {
615
+ return true ;
616
+ }
513
617
path .push (' L' );
514
- if (dfs (node .left , x, path)) return true ;
515
-
618
+ if (dfs (node .left , x, path)) {
619
+ return true ;
620
+ }
516
621
path[path .length - 1 ] = ' R' ;
517
- if (dfs (node .right , x, path)) return true ;
622
+ if (dfs (node .right , x, path)) {
623
+ return true ;
624
+ }
518
625
path .pop ();
519
-
520
626
return false ;
521
627
};
628
+ const pathToStart: string [] = [];
629
+ const pathToDest: string [] = [];
630
+ dfs (root, startValue, pathToStart);
631
+ dfs (root, destValue, pathToDest);
632
+ let i = 0 ;
633
+ while (pathToStart[i] === pathToDest[i]) {
634
+ ++ i;
635
+ }
636
+ return ' U' .repeat (pathToStart .length - i) + pathToDest .slice (i).join (' ' );
637
+ }
638
+ ` ` `
522
639
523
- const startPath: string [] = [];
524
- const destPath: string [] = [];
525
- dfs (root, start, startPath);
526
- dfs (root, dest, destPath);
640
+ #### JavaScript
527
641
642
+ ` ` ` js
643
+ /**
644
+ * Definition for a binary tree node.
645
+ * function TreeNode(val, left, right) {
646
+ * this.val = (val===undefined ? 0 : val)
647
+ * this.left = (left===undefined ? null : left)
648
+ * this.right = (right===undefined ? null : right)
649
+ * }
650
+ */
651
+ /**
652
+ * @param {TreeNode} root
653
+ * @param {number} startValue
654
+ * @param {number} destValue
655
+ * @return {string}
656
+ */
657
+ var getDirections = function (root , startValue , destValue ) {
658
+ const dfs = (node , x , path ) => {
659
+ if (node === null ) {
660
+ return false ;
661
+ }
662
+ if (node .val === x) {
663
+ return true ;
664
+ }
665
+ path .push (' L' );
666
+ if (dfs (node .left , x, path)) {
667
+ return true ;
668
+ }
669
+ path[path .length - 1 ] = ' R' ;
670
+ if (dfs (node .right , x, path)) {
671
+ return true ;
672
+ }
673
+ path .pop ();
674
+ return false ;
675
+ };
676
+ const pathToStart = [];
677
+ const pathToDest = [];
678
+ dfs (root, startValue, pathToStart);
679
+ dfs (root, destValue, pathToDest);
528
680
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
- }
681
+ while (pathToStart[i] === pathToDest[i]) {
682
+ ++ i;
683
+ }
684
+ return ' U' .repeat (pathToStart .length - i) + pathToDest .slice (i).join (' ' );
685
+ };
537
686
` ` `
538
687
539
688
<!-- tabs:end -->
0 commit comments