力扣每日一题:(687. 最长同值路径)

113 阅读3分钟

题目

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

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

示例1:

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

示例2:

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

二叉树的题目都逃不开前序、中序、后序、广度优先、深度优先遍历。刚开始做这道题的时候,我把这些方法在脑子里过了一遍,发现竟没有一个方法适合做这道题目的,无奈就去翻了题解,题解的代码是这样写的:

var longestUnivaluePath = function(root) {
    let res = 0;
    const dfs = (root) => {
        if (!root) {
            return 0;
        }
        let left = dfs(root.left), right = dfs(root.right);
        let left1 = 0, right1 = 0;
        if (root.left && root.left.val === root.val) {
            left1 = left + 1;
        }
        if (root.right && root.right.val === root.val) {
            right1 = right + 1;
        }
        res = Math.max(res, left1 + right1);
        return Math.max(left1, right1);
    }
    dfs(root);
    return res;
};

这样写有点类似于后序遍历的写法,但是题解说这是深度优先遍历的解法???

总感觉哪里有点不一样,直到后来去翻了翻更多的题解,看到有一个老哥写的很好,今天粗略的看一下,这道题便解出来了。leetcode.cn/problems/lo…

看完之后才知道,原来二叉树还有好多思路得要去学习,之前说的那些都是从根节点出发解决问题的方法,但是这道题并不是从根节点出发,这道题是属于求解最长路径,那位老哥也贴出来这种题目类型的模板:

int res=0;
int maxPath(TreeNode *root) //以root为路径起始点的最长路径
{
    if (!root)
        return 0;
    int left=maxPath(root->left);
    int right=maxPath(root->right);
    res = max(res, left + right + root->val); //更新全局变量  
    return max(left, right);   //返回左右路径较长者
}

这是c++的版本,这个模板和这道题目的解法几乎就是一模一样了,只要根据题目意思更改res的计算方法,这道题便解出来了。

下面贴一下ts代码

/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */

function longestUnivaluePath(root: TreeNode | null): number {
    let res: number = 0
    function maxPath(root: TreeNode | null): number {
        if (!root) return 0
        let left: number = maxPath(root.left)
        let right: number = maxPath(root.right)
        // 这里开始要根据题目意思修改
        let left1 = 0, right1 = 0
        if (root.left && root.left.val === root.val) {
            left1 = left + 1
        }
        if (root.right && root.right.val === root.val) {
            right1 = right + 1
        }
        res = Math.max(res, left1 + right1)
        return Math.max(left1, right1)
    }
    maxPath(root)
    return res
};

其实和官方给的题解一样的,只是吧js换成了用ts来写,这道题相当于只是套用二叉树计算最长道路的套路来解即可。

总结

  • 二叉树的解法还有很多,虽然今天题目不难,但是收获还是蛮大的,那个老哥的题解还没仔细看,有时间要再去好好看看,做做那些题目。
  • 看到题目先自己想想,如果没什么思路就多去翻翻题解,可以少走好多弯路,这道题要是去暴力求解,效率低不说,而且其实也没什么帮助。