給定一個二叉樹,找到最長的路徑,這個路徑中的每一個節點具備相同值。 這條路徑能夠通過也能夠不通過根節點。 node
注意:兩個節點之間的路徑長度由它們之間的邊數表示。 app
示例 1: ui
輸入: this
輸出: spa
2 code
示例 2: blog
輸入: ci
輸出: it
2
注意: 給定的二叉樹不超過10000個結點。 樹的高度不超過1000。 io
Intuition
We can think of any path (of nodes with the same values) as up to two arrows extending from it's root.
Specifically, the root of a path will be the unique node such that the parent of that node does not appear in the path, and an arrow will be a path where the root only has one child node in the path.
Then, for each node, we want to know what is the longest possible arrow extending left, and the longest possible arrow extending right? We can solve this using recursion.
Algorithm
Let arrow_length(node) be the length of the longest arrow that extends from the node. That will be 1 + arrow_length(node.left) if node.left exists and has the same value as node. Similarly for the node.right case.
While we are computing arrow lengths, each candidate answer will be the sum of the arrows in both directions from that node. We record these candidate answers and return the best one.
1 class Solution { 2 int ans; 3 public int longestUnivaluePath(TreeNode root) { 4 ans = 0; 5 arrowLength(root); 6 return ans; 7 } 8 public int arrowLength(TreeNode node) { 9 if (node == null) return 0; 10 int left = arrowLength(node.left) 11 int right = arrowLength(node.right); 12 int arrowLeft = 0, arrowRight = 0; 13 if (node.left != null && node.left.val == node.val) { 14 arrowLeft += left + 1; 15 } 16 if (node.right != null && node.right.val == node.val) { 17 arrowRight += right + 1; 18 } 19 ans = Math.max(ans, arrowLeft + arrowRight); 20 return Math.max(arrowLeft, arrowRight); 21 } 22 }