[路飞]_程序员必刷力扣题: 687. 最长同值路径

146 阅读2分钟

「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战

687. 最长同值路径

给定一个二叉树的 root ,返回 最长的路径的长度 ,这个路径中的 每个节点具有相同值 。 这条路径可以经过也可以不经过根节点。

两个节点之间的路径长度 由它们之间的边数表示。

示例1:

image.png

输入: root = [5,4,5,1,1,5]
输出: 2

示例2:

image.png

输入: root = [1,4,5,4,4,5]
输出: 2

提示:

  • 树的节点数的范围是 [0, 104] 
  • -1000 <= Node.val <= 1000
  • 树的深度将不超过 1000

递归

思路 由题可知,我们需要求出同样值所组成的最长路径,可以是经过根节点也可以不经过根节点,意思就是

  • 可以是某个节点并且连接着左子树往下或者右子树往下
  • 可以是从某个节点的左子树和右子树由根节点连接组成的一条同值路径

因为每个节点都可能是最长路径,所以我们一定要遍历到每一个节点,因此首先考虑递归的方式,这样就能处理每一个节点

具体实现:

声明最大路径max,以及处理每个节点的递归函数deepRoot

  • deepRoot,接受两个参数,root为当前节点,d为当前的路径长度
  • 声明left和right的初始长度为d
    • 如果子树的值等于root的值,那么继续往下递归,更新left和right的值为deepRoot(child,d+1),因为属于同值得情况,所以深度d加一
    • 如果子树的值不等于root的值,那么不必更新left和right,直接从路径长度0开始处理下一个节点即可
  • 顺便更新max的值,比较的一共有三个来源,left的长度;right的长度;(left-d)为当前节点左子树的路径长度,(right-d)当前节点到右子树的深度,第三个值为left+right-2 * d
  • 最后比较left和right长度,返回较长的路径值
  • 初始化deepRoot(root,0)从根节点,路径长度0开始递归
  • 最后返回max即可
var longestUnivaluePath = function (root) {
    // 当前节点的左右子树
    // 没有与当前节点一致的  //结束
    // 有一个一致  // 延伸
    // 有两个  判断
    var max = 0
    function deepRoot(root, d) {
        if (!root) return d
        var left = d , right = d
        if (root.left && root.left.val === root.val) {
            left = deepRoot(root.left, d + 1)
        } else {
            deepRoot(root.left, 0)
        }
        if (root.right && root.right.val === root.val) {
            right = deepRoot(root.right, d + 1)
        } else {
            deepRoot(root.right, 0)
        }
        var res = Math.max(left, right)

        max = Math.max(res, left + right - 2 * d, max)
        return res
    }
    deepRoot(root, 0)
    return max
};