687. Longest Univalue Path 二刷

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011934885/article/details/86479064

Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root.

Note: The length of path between two nodes is represented by the number of edges between them.

Example 1:

Input:

          5
         / \
        4   5
       / \   \
      1   1   5

Output:

2
Example 2:

Input:

          1
         / \
        4   5
       / \   \
      4   4   5

Output:

2

首先我们定义一个概念,就是path的类型,我自己分为两种,跨越根节点的可以横向连接的,我们叫双边路径,只能从上而下纵向连接的,我们叫单边路径。很多题都是两种路径混在一起考虑。这个时候递归就要注意了。最直接的递归可以很简洁,如下:

class Solution {
public:
    int longestUnivaluePath(TreeNode* root) {
        if (!root) return 0;
        int sub = max(longestUnivaluePath(root->left), longestUnivaluePath(root->right));
        return max(sub, helper(root->left, root->val) + helper(root->right, root->val));
    }
    int helper(TreeNode* node, int parent) {
        if (!node || node->val != parent) return 0;
        return 1 + max(helper(node->left, node->val), helper(node->right, node->val));
    }
};

就是要把单边递归单独拿出来讨论,这里的helper函数,就是返回从这个node开始,以parent为固定值的最长单边路径。但这么做效率比较低,重复的部分比较多。

这里想要增加的讨论就是,提醒自己,函数递归的过程中,返回值可以利用,有些别的reference变量也可以通过更新来利用。这里就是一个函数两种计算。代码如下:

class Solution {
public:
    int longestUnivaluePath(TreeNode* root) {
        int res = 0;
        helper(root, res);
        return res;
    }
    int helper(TreeNode* root, int &res) {
        if (root == NULL) return 0;
        int left = helper(root->left, res);
        int right = helper(root->right, res);
        if (root->left && root->left->val == root->val) 
            left++;
        else left = 0;
        if (root->right && root->right->val == root->val) 
            right++;
        else right = 0;
        res = max(res, left + right);
        return max(left, right);
    }
};

这里的helper返回的就是某个节点开始,最大的单边长度。但因为所有的双边都是两个单边组成的,我们在算完单边,返回左右里较大的那个之前,也完全可以加起来看看,此时,以这个节点为中心的双边路径该是多长,以此更新我们的res。

或者换种写法,但是一个意思,也可以写成:

class Solution {
public:
    int longestUnivaluePath(TreeNode* root) {
        int res = 0;
        if (root) helper(root, root->val, res);
        return res;
    }
    int helper(TreeNode* node, int parent, int &res) {
        if (node == NULL) return 0;
        int left = helper(node->left, node->val, res);
        int right = helper(node->right, node->val, res);
        res = max(res, left + right);
        if (node->val == parent) return 1 + max(left, right);
        return 0;
    }
};

很重要的一点是,你要知道helper函数返回的到底是什么,如何在更新的过程中包含了所有情况的讨论。

猜你喜欢

转载自blog.csdn.net/u011934885/article/details/86479064