二叉树 
      
    
      
      
      
        树 
      
    
      
      
      
        深度优先搜索 
      
    
   
  
    
      
       
  
  
    
      
    
    
      
       
  
题目描述 
给你一棵二叉树的根节点 root ,树中有 n 个节点,每个节点都有一个不同于其他节点且处于 1 到 n 之间的值。
另给你一个由 n 个值组成的行程序列 voyage ,表示 预期  的二叉树 先序遍历 
通过交换节点的左右子树,可以 翻转  该二叉树中的任意节点。例,翻转节点 1 的效果如下:
请翻转 最少  的树中节点,使二叉树的 先序遍历  与预期的遍历行程 voyage 相匹配  。 
如果可以,则返回 翻转的  所有节点的值的列表。你可以按任何顺序返回答案。如果不能,则返回列表 [-1]。
 
示例 1: 
输入: root = [1,2], voyage = [2,1]
输出: [-1]
解释: 翻转节点无法令先序遍历匹配预期行程。
 
示例 2: 
输入: root = [1,2,3], voyage = [1,3,2]
输出: [1]
解释: 交换节点 2 和 3 来翻转节点 1 ,先序遍历可以匹配预期行程。 
示例 3: 
输入: root = [1,2,3], voyage = [1,2,3]
输出: []
解释: 先序遍历已经匹配预期行程,所以不需要翻转节点。
 
 
提示: 
    树中的节点数目为 n 
    n == voyage.length1 <= n <= 1001 <= Node.val, voyage[i] <= n树中的所有值 互不相同  
    voyage 中的所有值 互不相同  
解法 
方法一:DFS 
我们可以通过深度优先搜索的方式遍历整棵树,用一个下标 \(i\)  记录当前遍历到的节点在数组 \(\textit{voyage}\)  中的下标,如果当前遍历到的节点的值不等于 \(\textit{voyage}[i]\) ,那么说明翻转后无法匹配,我们标记 \(\textit{ok}\)  为 false,并直接返回。否则,我们将 \(i\)  的值加 \(1\) ,然后判断当前节点是否有左子节点,如果没有,或者左子节点的值等于 \(\textit{voyage}[i]\) ,那么我们递归遍历当前的左右子节点;否则,我们需要翻转当前节点,然后再递归遍历当前的右子节点和左子节点。
搜索结束后,如果 \(\textit{ok}\)  为 true,那么说明翻转后可以匹配,我们返回答案数组 \(\textit{ans}\) ,否则返回 \([-1]\) 。
时间复杂度 \(O(n)\) ,空间复杂度 \(O(n)\) 。其中 \(n\)  是树中的节点数目。
Python3 Java C++ Go TypeScript 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 # 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   flipMatchVoyage ( self ,  root :  Optional [ TreeNode ],  voyage :  List [ int ])  ->  List [ int ]: 
        def   dfs ( root ): 
            nonlocal  i ,  ok 
            if  root  is  None  or  not  ok : 
                return 
            if  root . val  !=  voyage [ i ]: 
                ok  =  False 
                return 
            i  +=  1 
            if  root . left  is  None  or  root . left . val  ==  voyage [ i ]: 
                dfs ( root . left ) 
                dfs ( root . right ) 
            else : 
                ans . append ( root . val ) 
                dfs ( root . right ) 
                dfs ( root . left ) 
        ans  =  [] 
        i  =  0 
        ok  =  True 
        dfs ( root ) 
        return  ans  if  ok  else  [ - 1 ] 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 /** 
 * 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   { 
     private   int   i ; 
     private   boolean   ok ; 
     private   int []   voyage ; 
     private   List < Integer >   ans   =   new   ArrayList <> (); 
     public   List < Integer >   flipMatchVoyage ( TreeNode   root ,   int []   voyage )   { 
         this . voyage   =   voyage ; 
         ok   =   true ; 
         dfs ( root ); 
         return   ok   ?   ans   :   List . of ( - 1 ); 
     } 
     private   void   dfs ( TreeNode   root )   { 
         if   ( root   ==   null   ||   ! ok )   { 
             return ; 
         } 
         if   ( root . val   !=   voyage [ i ] )   { 
             ok   =   false ; 
             return ; 
         } 
         ++ i ; 
         if   ( root . left   ==   null   ||   root . left . val   ==   voyage [ i ] )   { 
             dfs ( root . left ); 
             dfs ( root . right ); 
         }   else   { 
             ans . add ( root . val ); 
             dfs ( root . right ); 
             dfs ( root . left ); 
         } 
     } 
} 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 /** 
 * 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 : 
     vector < int >   flipMatchVoyage ( TreeNode *   root ,   vector < int >&   voyage )   { 
         bool   ok   =   true ; 
         int   i   =   0 ; 
         vector < int >   ans ; 
         function < void ( TreeNode * ) >   dfs   =   [ & ]( TreeNode *   root )   { 
             if   ( ! root   ||   ! ok )   { 
                 return ; 
             } 
             if   ( root -> val   !=   voyage [ i ])   { 
                 ok   =   false ; 
                 return ; 
             } 
             ++ i ; 
             if   ( ! root -> left   ||   root -> left -> val   ==   voyage [ i ])   { 
                 dfs ( root -> left ); 
                 dfs ( root -> right ); 
             }   else   { 
                 ans . push_back ( root -> val ); 
                 dfs ( root -> right ); 
                 dfs ( root -> left ); 
             } 
         }; 
         dfs ( root ); 
         return   ok   ?   ans   :   vector < int > { -1 }; 
     } 
}; 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 /** 
 * Definition for a binary tree node. 
 * type TreeNode struct { 
 *     Val int 
 *     Left *TreeNode 
 *     Right *TreeNode 
 * } 
 */ 
func   flipMatchVoyage ( root   * TreeNode ,   voyage   [] int )   [] int   { 
     i   :=   0 
     ok   :=   true 
     ans   :=   [] int {} 
     var   dfs   func ( * TreeNode ) 
     dfs   =   func ( root   * TreeNode )   { 
         if   root   ==   nil   ||   ! ok   { 
             return 
         } 
         if   root . Val   !=   voyage [ i ]   { 
             ok   =   false 
             return 
         } 
         i ++ 
         if   root . Left   ==   nil   ||   root . Left . Val   ==   voyage [ i ]   { 
             dfs ( root . Left ) 
             dfs ( root . Right ) 
         }   else   { 
             ans   =   append ( ans ,   root . Val ) 
             dfs ( root . Right ) 
             dfs ( root . Left ) 
         } 
     } 
     dfs ( root ) 
     if   ! ok   { 
         return   [] int { - 1 } 
     } 
     return   ans 
} 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 /** 
 * 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   flipMatchVoyage ( root :   TreeNode   |   null ,   voyage :   number []) :   number []   { 
     let   ok   =   true ; 
     let   i   =   0 ; 
     const   ans :   number []   =   []; 
     const   dfs   =   ( root :   TreeNode   |   null ) :   void   =>   { 
         if   ( ! root   ||   ! ok )   { 
             return ; 
         } 
         if   ( root . val   !==   voyage [ i ++ ])   { 
             ok   =   false ; 
             return ; 
         } 
         if   ( ! root . left   ||   root . left . val   ===   voyage [ i ])   { 
             dfs ( root . left ); 
             dfs ( root . right ); 
         }   else   { 
             ans . push ( root . val ); 
             dfs ( root . right ); 
             dfs ( root . left ); 
         } 
     }; 
     dfs ( root ); 
     return   ok   ?   ans   :   [ - 1 ]; 
} 
 
 
    
    
    
    
      
  
    
      
  
     
  GitHub