题目

题目来源:力扣(LeetCode)

给你一个整数数组 nums,请你将该数组升序排列。

给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。
注意:两个节点之间的路径长度由它们之间的边数表示。

示例 1:

输入:

  1. 5<br /> / \<br /> 4 5<br /> / \ \<br /> 1 1 5<br />输出:<br />2

示例 2:

输入:

  1. 1<br /> / \<br /> 4 5<br /> / \ \<br /> 4 4 5<br />输出:<br />2

思路分析

路径长度 = 节点数 - 1

根据上述公式,要求出符合要求的路劲,就需要先求出二叉树中具有相同值的所有节点。

对于二叉树本身就具有递归这种性质的数据结构,我们需要把它看成“左子树-根节点-右子树”这种结构,就不要再囿于左子节点/右子节点这个思维里了。这道题其实可以看成是解决以root为路径起始点的最长路径,这其实就只有两种情况:
(1) 第一种是root和左子树(同值),如图中以4为路径起始点:root->lef
image.png

(2) 第二种是root和右子树(同值),如图中以4为路径起始点:root->right
image.png

(3) 还有一种特殊情况,那就是左子树-root-右子树(同值)
image.png

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. * @return {number}
  12. */
  13. // 返回以 root 节点为起点的最长同值路径
  14. // 该路径要么是以 root 为起点的左子树: root -> left ; 要么是以 root 为起点的右子树: root -> right
  15. var longestUnivaluePath = function (root) {
  16. let res = 0
  17. const dfs = (root) => {
  18. if (root == null) {
  19. return 0
  20. }
  21. const left = dfs(root.left) // root左子树的最长同值路径
  22. const right = dfs(root.right) // root右子树的最长同值路径
  23. let leftPath = 0, rightPath = 0
  24. // 从左右子树中选择最长的同值路径
  25. if (root.left && root.left.val == root.val) {
  26. leftPath = left + 1
  27. }
  28. if (root.right && root.right.val == root.val) {
  29. rightPath = right + 1
  30. }
  31. // 左子树 + 根 + 右子树 形成一条同值路径
  32. res = Math.max(res, leftPath + rightPath) // 记录全局
  33. return Math.max(rightPath, leftPath)
  34. }
  35. dfs(root)
  36. // 返回最长路径值
  37. return res
  38. }