[前端]_一起刷leetcode 687. 最长同值路径

181 阅读3分钟

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

题目

687. 最长同值路径

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

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

 

示例 1:

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

示例 2:

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

 

提示:

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

思路

  1. 树的问题一般可以转换为递归问题,不过我们要区分清楚递归的条件;
  2. 这道题目求最长的同值路径,那么我们先搞清楚这个路径的定义,简而言之就是经过某个节点的两条边可以组成一条路径;
  3. 那么我们需要考虑的是,经过哪个节点的边是最长的,所以我们可以用广度优先搜索去遍历每个节点作为根节点的情况,枚举每个节点作为根节点时的最长同值路径,取其中的最大值;
  4. 然后再求出任意节点最长同值的边长即可,求边长可以转换为递归问题,可以转换为求当前左右两个子节点的最大相等值的递归问题,然后子节点又再次递归去寻找它的更子节点的值即可。

举个例子: 我们求第一个案例的时候

image.png

首先枚举第一个节点作为根节点的可能性,然后求它和左右两条子边相等元素长度和的最大值:

左节点的值为4 不相等,不需要继续比较, 右节点的值为5继续递归查找,找出来的总节点为3个,路径等于节点值 - 1也就是等于2

然后继续枚举子节点4和5分别作为路径中根节点的情况继续做比较,4没有相等子节点,找到的结果为0, 第二个5的子节点有一个相等,路径为1, 然后拿这一轮的长度1 和上一轮的长度2做比较,取最大值即可。

一直反复递归到所有节点遍历完成为止即可,然后返回其中的最大值。

实现

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var longestUnivaluePath = function(root) {
    if (!root) return 0;
    
    let queue = [ root ];
    let maxPath = 0;

    // 深度优先搜索,枚举每个节点作为根节点的可能性
    while (queue.length) {
        queue = queue.reduce((total, cur) => {
            maxPath = Math.max(maxPath, findMaxNode(cur));

            cur.left && total.push(cur.left);
            cur.right && total.push(cur.right);
            return total;
        }, []);
    }

    return maxPath;
};

// 求当前节点作为根节点时的总路径
function findMaxNode(node) {
    return getMaxPath(node.left, node.val) + getMaxPath(node.right, node.val);
}

// 求节点的最长路径
function getMaxPath(node, val, count = 0) {
    if (!node) return count;

    if (node.val === val) {
        return Math.max(getMaxPath(node.left, val, count + 1), getMaxPath(node.right, val, count + 1));
    } else {
        return count;
    }
}

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。