[LintCode 614.] 二叉树的最长连续子序列 II

LintCode 614. 二叉树的最长连续子序列 II

问题描述

给定一棵二叉树,找到最长连续序列(单调且相邻节点值相差为1)路径的长度(节点数)。
路径起点跟终点可以为二叉树的任意节点。

样例

例1:

输入:
{1,2,0,3}
输出:
4
解释:

    1
   / \
  2   0
 /
3
0-1-2-3

例2:

输入:
{3,2,2}
输出:
2
解释:

    3
   / \
  2   2
2-3

解题思路

这是一道递归题目,显然我们不可能枚举所有的路径,那就让每个结点来记录自己身上的最大路径长度。
需要注意的是,对于树中的结点,自身最大单调路径长度,以及需要提供给父节点的最大单调路径长度,是不一样的。
对于自身而言,单调路径长度,可以是两个子结点上的单调路径拼接而来,一边单调递增一边单调递减就可以了。
对于父节点,他想知道的就只有子结点作为链条端点时候的路径长度,单增单减的都要。
所以做法就很清晰了,函数返回值用于返回自增自减两个最大长度,全局变量用于获取全局最大值。

参考答案

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

struct Res {
    int uplen;
    int downlen;
};

class Solution {
    int longest;
public:
    /**
     * @param root: the root of binary tree
     * @return: the length of the longest consecutive sequence path
     */
    int longestConsecutive2(TreeNode * root) {
        // write your code here
        if (root == NULL) return 0;
        longest = 0;
        longestFind(root);
        return longest;
    }
    Res longestFind(TreeNode* r) {
        if (r == NULL) return { 0, 0 };
        int up = 1, down = 1;
        if (r->left) {
            Res res = longestFind(r->left);
            if (r->val + 1 == r->left->val) down = max(down, res.downlen + 1);
            if (r->val - 1 == r->left->val) up  = max(up, res.uplen + 1);
        }
        if (r->right) {
            Res res = longestFind(r->right);
            if (r->val + 1 == r->right->val) down = max(down, res.downlen + 1);
            if (r->val - 1 == r->right->val) up = max(up, res.uplen + 1);
        }
        longest = max(longest, up + down - 1);
        return {up, down};
    }
};
posted @ 2021-01-12 11:31  与MPI做斗争  阅读(129)  评论(0编辑  收藏  举报