二叉树 
      
    
      
      
      
        树 
      
    
      
      
      
        深度优先搜索 
      
    
   
  
    
      
       
     
  
  
    
      
    
    
      
       
     
  
    
题目描述 
给定二叉树的根节点 root,找出存在于 不同  节点 A 和 B 之间的最大值 V,其中 V = |A.val - B.val|,且 A 是 B 的祖先。
(如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)
 
示例 1: 
输入: root = [8,3,10,1,6,null,14,null,null,4,7,13]
输出: 7
解释:  
我们有大量的节点与其祖先的差值,其中一些如下:
|8 - 3| = 5
|3 - 7| = 4
|8 - 1| = 7
|10 - 13| = 3
在所有可能的差值中,最大值 7 由 |8 - 1| = 7 得出。
 
示例 2: 
输入: root = [1,null,2,null,0,3]
输出: 3
 
 
提示: 
    树中的节点数在 2 到 5000 之间。 
    0 <= Node.val <= 105  
 
解法 
方法一:DFS 
对于每个节点,求其与祖先节点的最大差值,我们只需要求出该节点与祖先节点最大值和最小值的差值。取所有节点与祖先节点差值的最大值即可。
因此,我们设计一个函数 \(dfs(root, mi, mx)\) ,表示当前搜索到的节点为 \(root\) ,其祖先节点的最大值为 \(mx\) ,最小值为 \(mi\) ,函数内更新最大差值 \(ans\) 。
函数 \(dfs(root, mi, mx)\)  的逻辑如下:
若 \(root\)  为空,直接返回。 
否则,我们更新 \(ans = max(ans, |mi - root.val|, |mx - root.val|)\) 。 
然后更新 \(mi = min(mi, root.val)\) , \(mx = max(mx, root.val)\) ,并且递归搜索左右子树。 
 
在主函数中,我们调用 \(dfs(root, root.val, root.val)\) ,最后返回 \(ans\)  即可。
时间复杂度 \(O(n)\) ,空间复杂度 \(O(n)\) 。其中 \(n\)  为二叉树节点个数。
Python3 Java C++ Go TypeScript JavaScript C# 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 # 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   maxAncestorDiff ( self ,  root :  Optional [ TreeNode ])  ->  int : 
        def   dfs ( root :  Optional [ TreeNode ],  mi :  int ,  mx :  int ): 
            if  root  is  None : 
                return 
            nonlocal  ans 
            ans  =  max ( ans ,  abs ( mi  -  root . val ),  abs ( mx  -  root . val )) 
            mi  =  min ( mi ,  root . val ) 
            mx  =  max ( mx ,  root . val ) 
            dfs ( root . left ,  mi ,  mx ) 
            dfs ( root . right ,  mi ,  mx ) 
        ans  =  0 
        dfs ( root ,  root . val ,  root . val ) 
        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 /** 
 * 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   ans ; 
     public   int   maxAncestorDiff ( TreeNode   root )   { 
         dfs ( root ,   root . val ,   root . val ); 
         return   ans ; 
     } 
     private   void   dfs ( TreeNode   root ,   int   mi ,   int   mx )   { 
         if   ( root   ==   null )   { 
             return ; 
         } 
         int   x   =   Math . max ( Math . abs ( mi   -   root . val ),   Math . abs ( mx   -   root . val )); 
         ans   =   Math . max ( ans ,   x ); 
         mi   =   Math . min ( mi ,   root . val ); 
         mx   =   Math . max ( mx ,   root . val ); 
         dfs ( root . left ,   mi ,   mx ); 
         dfs ( root . right ,   mi ,   mx ); 
     } 
} 
 
 
 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. 
 * 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 : 
     int   maxAncestorDiff ( TreeNode *   root )   { 
         int   ans   =   0 ; 
         function < void ( TreeNode * ,   int ,   int ) >   dfs   =   [ & ]( TreeNode *   root ,   int   mi ,   int   mx )   { 
             if   ( ! root )   { 
                 return ; 
             } 
             ans   =   max ({ ans ,   abs ( mi   -   root -> val ),   abs ( mx   -   root -> val )}); 
             mi   =   min ( mi ,   root -> val ); 
             mx   =   max ( mx ,   root -> val ); 
             dfs ( root -> left ,   mi ,   mx ); 
             dfs ( root -> right ,   mi ,   mx ); 
         }; 
         dfs ( root ,   root -> val ,   root -> val ); 
         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 /** 
 * Definition for a binary tree node. 
 * type TreeNode struct { 
 *     Val int 
 *     Left *TreeNode 
 *     Right *TreeNode 
 * } 
 */ 
func   maxAncestorDiff ( root   * TreeNode )   ( ans   int )   { 
     var   dfs   func ( * TreeNode ,   int ,   int ) 
     dfs   =   func ( root   * TreeNode ,   mi ,   mx   int )   { 
         if   root   ==   nil   { 
             return 
         } 
         ans   =   max ( ans ,   max ( abs ( mi - root . Val ),   abs ( mx - root . Val ))) 
         mi   =   min ( mi ,   root . Val ) 
         mx   =   max ( mx ,   root . Val ) 
         dfs ( root . Left ,   mi ,   mx ) 
         dfs ( root . Right ,   mi ,   mx ) 
     } 
     dfs ( root ,   root . Val ,   root . Val ) 
     return 
} 
func   abs ( x   int )   int   { 
     if   x   <   0   { 
         return   - x 
     } 
     return   x 
} 
 
 
 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 { 
 *     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   maxAncestorDiff ( root :   TreeNode   |   null ) :   number   { 
     const   dfs   =   ( root :   TreeNode   |   null ,   mi :   number ,   mx :   number ) :   void   =>   { 
         if   ( ! root )   { 
             return ; 
         } 
         ans   =   Math . max ( ans ,   Math . abs ( root . val   -   mi ),   Math . abs ( root . val   -   mx )); 
         mi   =   Math . min ( mi ,   root . val ); 
         mx   =   Math . max ( mx ,   root . val ); 
         dfs ( root . left ,   mi ,   mx ); 
         dfs ( root . right ,   mi ,   mx ); 
     }; 
     let   ans :   number   =   0 ; 
     dfs ( root ,   root . val ,   root . val ); 
     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 /** 
 * 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 
 * @return {number} 
 */ 
var   maxAncestorDiff   =   function   ( root )   { 
     let   ans   =   0 ; 
     const   dfs   =   ( root ,   mi ,   mx )   =>   { 
         if   ( ! root )   { 
             return ; 
         } 
         ans   =   Math . max ( ans ,   Math . abs ( mi   -   root . val ),   Math . abs ( mx   -   root . val )); 
         mi   =   Math . min ( mi ,   root . val ); 
         mx   =   Math . max ( mx ,   root . val ); 
         dfs ( root . left ,   mi ,   mx ); 
         dfs ( root . right ,   mi ,   mx ); 
     }; 
     dfs ( root ,   root . val ,   root . val ); 
     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 /** 
 * Definition for a binary tree node. 
 * public class TreeNode { 
 *     public int val; 
 *     public TreeNode left; 
 *     public TreeNode right; 
 *     public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { 
 *         this.val = val; 
 *         this.left = left; 
 *         this.right = right; 
 *     } 
 * } 
 */ 
public   class   Solution   { 
     private   int   ans ; 
     public   int   MaxAncestorDiff ( TreeNode   root )   { 
         dfs ( root ,   root . val ,   root . val ); 
         return   ans ; 
     } 
     private   void   dfs ( TreeNode   root ,   int   mi ,   int   mx )   { 
         if   ( root   ==   null )   { 
             return ; 
         } 
         int   x   =   Math . Max ( Math . Abs ( mi   -   root . val ),   Math . Abs ( mx   -   root . val )); 
         ans   =   Math . Max ( ans ,   x ); 
         mi   =   Math . Min ( mi ,   root . val ); 
         mx   =   Math . Max ( mx ,   root . val ); 
         dfs ( root . left ,   mi ,   mx ); 
         dfs ( root . right ,   mi ,   mx ); 
     } 
} 
 
 
 
 
  
  
  
    
    
    
    
      
  
    
      
  
     
   
  GitHub