首页 > 代码库 > LeetCode OJ - Binary Tree Maximum Path

LeetCode OJ - Binary Tree Maximum Path

这道题需要注意的地方有以下一些:

1. 求从子树中的某节点到当前节点的最大路径不能采用递归方法,因为这个部分会被反复的调用,如果用递归,会使得之前已经计算过的节点被重复计算,使得时间复杂度特别高;

2. 树中有节点的值是负数的。

下面是AC代码。(我发现AC并不代表代码真的完全正确!!)

 1 /**
 2      * Given a binary tree, find the maximum path sum.
 3      * The path may start and end at any node in the tree.
 4      * there are negative numbers
 5      * {9,6,-3,#,#,-6,2,#,#,2,#,-6,-6,-6}
 6      * @param root
 7      * @return
 8      */
 9     public int maxPathSum(TreeNode root){
10         if(root == null)
11             return 0;
12         return subProblem(root);
13     }
14     /**
15      * 
16      * @param root
17      * @return
18      */
19     private int subProblem(TreeNode root){
20         
21         if(root == null)
22             return Integer.MIN_VALUE;
23         if(root.left == null && root.right == null)
24             return root.val;
25         //左子树的最大路劲和
26         int left = subProblem(root.left);
27         //右子树的最大路径和
28         int right = subProblem(root.right);
29         //经过root节点的最大路径和
30         int lc = maxSinglePath2(root.left);
31         int rc = maxSinglePath2(root.right);
32         int mid = lc>0?lc:0;
33         mid = rc>0? mid+rc:mid;
34         
35         return Math.max(left, right)>mid+root.val?Math.max(left, right):mid+root.val;
36     }
37     /**
38     /**
39      * 这种递归求从某个节点到叶节点路径上和最大的方法,容易出现TLE
40      * 因为这个方法要被subProblem反复使用
41      * 
42     private int maxSinglePath(TreeNode root){
43         if(root==null)
44             return 0;
45         if(root.left==null && root.right ==null)
46             return root.val;
47         int lc = maxSinglePath(root.left);
48         int lr = maxSinglePath(root.right);
49         return Math.max(lc, lr)+root.val;
50     }*/
51     //通过另外开辟一个全局变量,存储从底层开始到每个节点(key)的路径的最大和
52     //这样可以避免出现已经计算过的节点被反复计算
53     HashMap<TreeNode,Integer> ns = new HashMap<TreeNode,Integer>();
54     private int maxSinglePath2(TreeNode root){
55         if(root==null)
56             return 0;
57         if(root.left==null && root.right ==null)
58         {
59             ns.put(root, root.val);
60             return root.val;
61         }
62         int lc,rc;//到左、右节点的最大路径和
63         if(root.left!=null && ns.containsKey(root.left))
64             lc = ns.get(root.left);
65         else
66             lc = maxSinglePath2(root.left);
67         if(root.right!=null && ns.containsKey(root.right))
68             rc = ns.get(root.right);
69         else
70             rc = maxSinglePath2(root.right);
71         //this is very important!!!!!! 因为节点的值可能为负数,如果到左右两节点的最大路径和是负数的话,我就直接从当前节点作为当前节点的路径最大和的起始点
72         if(Math.max(lc, rc)>0)
73             ns.put(root, Math.max(lc, rc)+root.val);
74         else
75             ns.put(root, root.val);
76         return ns.get(root);
77         //return Math.max(lc, rc)+root.val;
78     }