程序员代码面试指南第二版 37.在二叉树中找到累加和为指定值的最长路径长度
题目描述
给定一颗二叉树和一个整数 sum,求累加和为 sum 的最长路径长度。路径是指从某个节点往下,每次最多选择一个孩子节点或者不选所形成的节点链。
输入描述:
第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
以下 n 行每行四个整数 fa,lch,rch,val,表示 fa 的左儿子为 lch,右儿子为 rch。val 表示 fa 节点的值(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
输出描述:
输出一个整数表示最长链的长度。
示例1
输入
9 1
1 2 3 -3
2 4 5 3
4 0 0 1
5 8 9 0
8 0 0 1
9 0 0 6
3 6 7 -9
6 0 0 2
7 0 0 1
6
输出
4
第一次做; 哈希表前缀和方法; 该方法的通用特点:需要用到前缀和哈希表, preSum, (每个元素的位置信息); 在二叉树中使用该方法要单独注意: 如果curSum是在当前层产生的, 那么需要将curSum从sumMap中删掉, 避免出现一个分支使用了另一个分支上的前缀和的错误情况; 递归函数逻辑: 求以当前节点为结尾的所有路径上和为k的最长路径; 比左神方法中的递归函数少用了一个参数:maxLen, 这个值仅作为返回值即可, 不用作为形参
import java. util. Scanner;
import java. util. HashMap;
public class Main {
public static void main ( String[ ] args) {
Scanner sc = new Scanner ( System. in) ;
String[ ] str = sc. nextLine ( ) . split ( " " ) ;
int n = Integer. parseInt ( str[ 0 ] ) ;
int r = Integer. parseInt ( str[ 1 ] ) ;
TreeNode[ ] nodes = new TreeNode [ n+ 1 ] ;
for ( int i= 1 ; i<= n; i++ ) {
nodes[ i] = new TreeNode ( 0 ) ;
}
for ( int i= 0 ; i< n; i++ ) {
str = sc. nextLine ( ) . split ( " " ) ;
int index = Integer. parseInt ( str[ 0 ] ) ;
int leftIndex = Integer. parseInt ( str[ 1 ] ) ;
int rightIndex = Integer. parseInt ( str[ 2 ] ) ;
int val = Integer. parseInt ( str[ 3 ] ) ;
nodes[ index] . val = val;
nodes[ index] . left = nodes[ leftIndex] ;
nodes[ index] . right = nodes[ rightIndex] ;
}
int k = Integer. parseInt ( sc. nextLine ( ) ) ;
TreeNode root = nodes[ r] ;
HashMap< Integer, Integer> sumMap = new HashMap < > ( ) ;
sumMap. put ( 0 , - 1 ) ;
int res = core ( root, sumMap, 0 , 0 , k) ;
System. out. println ( res) ;
}
public static int core ( TreeNode root, HashMap< Integer, Integer> sumMap, int preSum, int level, int k) {
if ( root== null)
return 0 ;
int max = 0 ;
int curSum = preSum + root. val;
if ( ! sumMap. containsKey ( curSum) )
sumMap. put ( curSum, level) ;
if ( sumMap. containsKey ( curSum- k) ) {
max = Math. max ( max, level - sumMap. get ( curSum- k) ) ;
}
int leftRes = core ( root. left, sumMap, curSum, level+ 1 , k) ;
int rightRes = core ( root. right, sumMap, curSum, level+ 1 , k) ;
if ( sumMap. get ( curSum) == level)
sumMap. remove ( curSum) ;
return Math. max ( max, Math. max ( leftRes, rightRes) ) ;
}
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode ( int val) {
this . val = val;
}
}
}