【LeetCode】Q687-最长同值路径

Q687. 最长同值路径

题目描述:

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

          5
         / \
        4   5
       / \   \
      1   1   5

输出:2

示例:

          1
         / \
        4   5
       / \   \
      4   4   5

输出:2
注意:注意: 给定的二叉树不超过10000个结点。 树的高度不超过1000。

思路分析:
本题最大收获:解决递归的问题很多时候需要借助辅助函数完成,辅助函数的作用并不一定是直接解决问题本身!!!
【LeetCode】Q687-最长同值路径_第1张图片
现在假设有一二叉树如上图所示,那么最长同值路径应该为:h<-d<-b<-a->c->g->k,可以将该最长同值路径记为f(a),表示以节点a为根节点的最长同值路径;

现在考虑a节点的左子节点b:

对于节点b而言,以b为根节点的最长同值路径为:h<-d<-b->c,仍然根据上面的记法记为f(b),表示以b节点为根节点的最长同值路径;

考虑a节点的右子节点c:

对于节点c而言,以c为根节点的最长同值路径为:f<-c->g->k,仍然根据上面的记法记为f©,表示以c节点为根节点的最长同值路径。

根据递归的思路,接下来我们需要考虑的问题是,如何通过f(b),f©得到f(a)呢?或者说,能通过f(b),f©直接得到f(a)吗?答案是不能的,或者说是非常困难的。

进一步地可以仔细观察f(a)的组成,不难发现f(a)实际是由f(b)的一部分和f©的一部分组成的,f(a)中属于f(b)的那部分h<-d<-b正是包含b节点的单侧最长同值路径,f(a)中属于f©的那部分c->g->k正是包含c
节点的单侧最长同值路径。

经过分析,我们不能直接定义一个功能为求解最长同值路径的函数,而需要定义一个求解单侧最长同值路径的函数,而最终需要返回的结果则在求解的过程中进行记录。

代码实现:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int ans;
    public int longestUnivaluePath(TreeNode root) {
        ans = 0;
        arrowLength(root);
        return ans;      
    }
    //该函数的功能是返回以该节点为根节点的单侧最长同值路径
    public int arrowLength(TreeNode node){
        //如果当前节点为空,则以该节点为根节点的单侧最长路径为0
        if(node == null)
        return 0;
        //以当前节点左子节点为根节点的单侧最长同值路径
        int subLeftLength = arrowLength(node.left);
        //以当前节点右子节点为根节点的单侧最长同值路径
        int subRightLength = arrowLength(node.right);
        //该节点的左侧最长同值路径
        int leftLength = 0;
        //该节点的右侧最长同值路径
        int rightLength = 0;
        //如果该节点的值与左节点的值相同
        if(null != node.left  && node.left.val == node.val){
            leftLength += subLeftLength + 1;
        }
        //如果该节点的值与右节点的值相同
        if(null != node.right && node.right.val == node.val){
            rightLength += subRightLength + 1;
        }
        //记录最长同值路径
        ans = Math.max(ans , leftLength + rightLength);
        //返回该节点的最长单侧同值路径,如果该节点的值与其左右子节点的值都不等,则返回0
        return Math.max(leftLength, rightLength);
    }
}

你可能感兴趣的:(数据结构与算法笔记)