题目描述:给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。这条路径可以经过也可以不经过根节点。
注意:两个节点之间的路径长度由它们之间的边数表示。
示例1:
输入:
5
/ \
4 5
/ \ \
1 1 5
输出:2
示例 2:
输入:
1
/ \
4 5
/ \ \
4 4 5
输出:2
注意: 给定的二叉树不超过10000个结点.树的高度不超过1000。
先解释一下题目,就是让我们找到一个路径,这个路径上面的值都相同,而且可以不经过根节点,例如,例2中的4-4-4这样的。
刚做这道题的时候有种错觉,觉得就是在遍历二叉树,其实不然,求最长路径是没有回头路可走的,也就是说,每次递归只能返回该结点的左右结点的最大路径长度,不能返回两者之和。
但是求最大值的和是要用一个全局变量记录的,但是不能返回。
思路:如果当前节点值不和父节点相同,则返回0;若相同,则返回左右子树中边数较多的一个,加1是因为当他与父节点的值相同时,和父节点还有一个连线。maxL用来动态记录边数最多的路径。
# Definition for a binary tree node. class TreeNode(object): def __init__(self, x): self.val = x self.left = None self.right = None class Solution (object): def longestUnivaluePath(self, root): """ :type root: TreeNode :rtype: int """ maxL = 0 def getMaxL(node,val): nonlocal maxL #用来在函数或其他作用域中使用外层(非全局)变量。 if node == None: return 0 leftMaxL = getMaxL(node.left,node.val) rightMaxL = getMaxL(node.right,node.val) maxL = max(maxL, leftMaxL + rightMaxL) print('node=%s,maxL=%s'%(node.val,maxL)) if node.val == val: return max(leftMaxL,rightMaxL) + 1 else: return 0 if root != None: getMaxL(root,root.val) return maxL def longestUnivaluePath1(self,root): res = 0 def dns(node): nonlocal res if node == None: return 0 lmax = dns(node.left) rmax = dns(node.right) if node.left and node.left.val == node.val: lmax = lmax + 1 else: lmax = 0 if node.right and node.right.val == node.val: rmax = rmax + 1 else: rmax = 0 res = max(res,lmax+rmax) #最大值是当前的最大值或者左右孩子路径的和。 return max(lmax,rmax) #返回值是左右路径中的最大值,因为它还需要和父节点继续构建路径。 dns(root) return res root = TreeNode(1) Node1 = TreeNode(4) Node2 = TreeNode(5) Node3 = TreeNode(5) Node4 = TreeNode(4) Node5 = TreeNode(5) Node6 = TreeNode(5) root.left = Node1 root.right = Node2 Node1.left = Node3 Node1.right = Node4 Node2.right = Node5 Node3.left = Node5 Node5.left = Node6 S = Solution() res = S.longestUnivaluePath1(root) print(res)
结果为2