Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree.

Especially, this path can be either increasing or decreasing. For example, [1,2,3,4] and [4,3,2,1] are both considered valid, but the path [1,2,4,3] is not valid. On the other hand, the path can be in the child-Parent-child order, where not necessarily be parent-child order.

Example 1:

Input:
1
/ \
2 3
Output: 2
Explanation: The longest consecutive path is [1, 2] or [2, 1].

Example 2:

Input:
2
/ \
1 3
Output: 3
Explanation: The longest consecutive path is [1, 2, 3] or [3, 2, 1].

Note: All the values of tree nodes are in the range of [-1e7, 1e7].

128. Longest Consecutive Sequence 的拓展,还是找最长的连续序列,这一题里可以是升序也可以是降序,而且不必从父结点到子结点,可以子父子节点。

解法:递归。

对于以root为根的树来说,符合条件的path可以分为两类:一类是不经过root的,一类是经过root的。不经过root的可以直接通过对其左子树和右子树的递归调用获得。经过root的有两种:一种是在其左子树上由下到上连续递增到root之后,在其右子树上由上到下连续递增;一种是在其左子树上由下到上连续递减到root之后,在其右子树上由上到下继续连续递减。我们取所有可能类型的path的最长长度即可。

Compared with 298. Binary Tree Longest Consecutive Sequence, this question includes more different conditions since it allows for:

  1. both increasing and decreasing order from a follows the parent-child path.
  2. child-parent-child path.

Hence this question actually contains 2 subproblems to solve:

  1. what is the longest increasing consecutive parent-child path sequence given a root node?
  2. what is the longest decreasing consecutive parent-child path sequence given a root node?

Based on the above 2 sub-solution, we know that the longest consecutive sequence for a given root is longest_increasing_sequence + longest_decreasing_sequence from this root. We can simply add up this 2 value because the longest increasing consecutive sequence and longest decreasing consecutive sequence is guaranteed to showed up in different child path (otherwise there will be a contradiction--a child's value cannot be greater than and less than the root's value at the same time).

If the root's value's value is not consecutive with a child's value, then the length of current sequence is simply 1.

Time complexity: O(n) where n is the number of nodes in the tree.

Space complexity: O(logn) on average for the recursion stack since this is a binary tree.

Java:

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int max = 0;
public int longestConsecutive(TreeNode root) {
getLongestConsecutive(root);
return max;
} private int[] getLongestConsecutive(TreeNode root) {
// returns [longest_decreasing_length_from_root, longest_increasing_length_from_root]
if (root == null) return new int[]{0, 0};
int[] left = getLongestConsecutive(root.left);
int[] right = getLongestConsecutive(root.right);
int dcr = 1, icr = 1;
if (root.left != null) {
if (root.left.val == root.val + 1) {
icr = left[1] + 1;
}
if (root.left.val == root.val - 1) {
dcr = left[0] + 1;
}
}
if (root.right != null) {
if (root.right.val == root.val + 1) {
icr = Math.max(icr, right[1] + 1);
} if (root.right.val == root.val - 1) {
dcr = Math.max(dcr, right[0] + 1);
}
}
max = Math.max(max, dcr + icr - 1);
return new int[]{dcr, icr};
}
}  

Python:

# Time:  O(n)
# Space: O(h)
class Solution(object):
def longestConsecutive(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def longestConsecutiveHelper(root):
if not root:
return 0, 0
left_len = longestConsecutiveHelper(root.left)
right_len = longestConsecutiveHelper(root.right)
cur_inc_len, cur_dec_len = 1, 1
if root.left:
if root.left.val == root.val + 1:
cur_inc_len = max(cur_inc_len, left_len[0] + 1)
elif root.left.val == root.val - 1:
cur_dec_len = max(cur_dec_len, left_len[1] + 1)
if root.right:
if root.right.val == root.val + 1:
cur_inc_len = max(cur_inc_len, right_len[0] + 1)
elif root.right.val == root.val - 1:
cur_dec_len = max(cur_dec_len, right_len[1] + 1)
self.max_len = max(self.max_len, cur_dec_len + cur_inc_len - 1)
return cur_inc_len, cur_dec_len self.max_len = 0
longestConsecutiveHelper(root)
return self.max_len

Python: 一次遍历

class Solution(object):
def solve(self, root):
inc = dec = 0
for child in (root.left, root.right):
if not child: continue
cinc, cdec = self.solve(child)
if child.val == root.val - 1:
dec = max(dec, cdec)
elif child.val == root.val + 1:
inc = max(inc, cinc)
self.ans = max(self.ans, inc + dec + 1)
return inc + 1, dec + 1 def longestConsecutive(self, root):
"""
:type root: TreeNode
:rtype: int
"""
self.ans = 0
if root: self.solve(root)
return self.ans

Python: 递归 + 遍历二叉树, Time: O(n^2)

class Solution(object):
def maxLength(self, root, val, delta):
lchild, rchild = root.left, root.right
lsize = rsize = 0
if lchild and lchild.val == val + delta:
lsize = self.maxLength(lchild, val + delta, delta)
if rchild and rchild.val == val + delta:
rsize = self.maxLength(rchild, val + delta, delta)
return 1 + max(lsize, rsize) def longestConsecutive(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root: return 0
lchild, rchild = root.left, root.right
lsize = rsize = 0
clen = 1
if lchild and abs(lchild.val - root.val) == 1:
lsize = self.maxLength(lchild, lchild.val, lchild.val - root.val)
if rchild and abs(rchild.val - root.val) == 1:
rsize = self.maxLength(rchild, rchild.val, rchild.val - root.val)
if lchild and rchild and lchild.val != rchild.val:
clen += lsize + rsize
else:
clen += max(lsize, rsize)
llen = self.longestConsecutive(lchild)
rlen = self.longestConsecutive(rchild)
return max(clen, llen, rlen)

C++:

// Time:  O(n)
// Space: O(h) /**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int longestConsecutive(TreeNode* root) {
int max_len = 0;
longestConsecutiveHelper(root, &max_len);
return max_len;
} pair<int, int> longestConsecutiveHelper(TreeNode *root, int *max_len) {
if (!root) {
return {0, 0};
}
const pair<int, int> left_len = longestConsecutiveHelper(root->left, max_len);
const pair<int, int> right_len = longestConsecutiveHelper(root->right, max_len); int cur_inc_len = 1, cur_dec_len = 1;
if (root->left) {
if (root->left->val == root->val + 1) {
cur_inc_len = max(cur_inc_len, left_len.first + 1);
} else if (root->left->val == root->val - 1){
cur_dec_len = max(cur_dec_len, left_len.second + 1);
}
}
if (root->right) {
if (root->right->val == root->val + 1) {
cur_inc_len = max(cur_inc_len, right_len.first + 1);
} else if (root->right->val == root->val - 1) {
cur_dec_len = max(cur_dec_len, right_len.second + 1);
}
}
*max_len = max(*max_len, cur_dec_len + cur_inc_len - 1);
return {cur_inc_len, cur_dec_len};
}
};

C++:

class Solution {
public:
int longestConsecutive(TreeNode* root) {
int res = 0;
helper(root, root, res);
return res;
}
pair<int, int> helper(TreeNode* node, TreeNode* parent, int& res) {
if (!node) return {0, 0};
auto left = helper(node->left, node, res);
auto right = helper(node->right, node, res);
res = max(res, left.first + right.second + 1);
res = max(res, left.second + right.first + 1);
int inc = 0, dec = 0;
if (node->val == parent->val + 1) {
inc = max(left.first, right.first) + 1;
} else if (node->val + 1 == parent->val) {
dec = max(left.second, right.second) + 1;
}
return {inc, dec};
}
};

C++:  

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

  

  

类似题目:

[LeetCode] 298. Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

[LeetCode] 128. Longest Consecutive Sequence 求最长连续序列

[LeetCode] 300. Longest Increasing Subsequence 最长递增子序列

[LintCode] 619 Binary Tree Longest Consecutive Sequence III 二叉树最长连续序列 III

  

All LeetCode Questions List 题目汇总

[LeetCode] 549. Binary Tree Longest Consecutive Sequence II 二叉树最长连续序列之 II的更多相关文章

  1. [LintCode] 619 Binary Tree Longest Consecutive Sequence III 二叉树最长连续序列 III

    Given a k-ary tree, find the length of the longest consecutive sequence path. The path could be star ...

  2. LeetCode 549. Binary Tree Longest Consecutive Sequence II

    原题链接在这里:https://leetcode.com/problems/binary-tree-longest-consecutive-sequence-ii/description/ 题目: G ...

  3. [LeetCode] 549. Binary Tree Longest Consecutive Sequence II_ Medium tag: DFS recursive

    Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree. Especia ...

  4. [LeetCode] 298. Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

  5. LeetCode 298. Binary Tree Longest Consecutive Sequence

    原题链接在这里:https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/ 题目: Given a binary t ...

  6. [LeetCode] Binary Tree Longest Consecutive Sequence II 二叉树最长连续序列之二

    Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree. Especia ...

  7. LeetCode Binary Tree Longest Consecutive Sequence

    原题链接在这里:https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/ 题目: Given a binary t ...

  8. [Locked] Binary Tree Longest Consecutive Sequence

    Binary Tree Longest Consecutive Sequence Given a binary tree, find the length of the longest consecu ...

  9. [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

随机推荐

  1. kali 攻击wordpress + trunkey linux wordpress 安装方法

    Kali-linux攻击WordPress和其他应用程序   今天越来越多的企业利用SAAS(Software as a Service)工具应用在他们的业务中.例如,他们经常使用WordPress作 ...

  2. Python 利用函数、列表来实现计算天数

    这几天课程学习了列表的操作,结合以前的函数知识,编写了一个能够判断天数的代码 源码如下 def is_year(year): return year % 4 == 0 and year % 100 ! ...

  3. python开发笔记-如何做数据准备

    时间格式: >>> from datetime import date >>> firstday = date.fromtimestamp(1464010200) ...

  4. linux下用vim写Python自动缩进的配置

    #首先用 find / -name vimrc 找到vimrc文件#一般在 /etc/vimrc#进入vimrc后加入以下命令 set number set autoindent set shiftw ...

  5. oracle 年龄分档,不用case when 的方法

    一般我们出分档数据都是case when ,但是如果是对年龄等一些字段进行细分,比如五岁一档,我们如果用case when就会特别麻烦,写的特别多,这里我介绍一种简单的方法,对细分的字段进行处理: 建 ...

  6. 文件上传相关报错: The current request is not a multipart request或is a MultipartResolver configured?

    1:from中涉及到图片上传的就要用post提交方式.否则就会报这个错误. 2:第一中:在jsp页面的<head></head>标签里面加上<meta http-equi ...

  7. CORS 跨域 node |XMLHttpRequest 跨域提交数据 node

    node服务端 app.post('/getdata',function(req,res,next){ req.setEncoding('utf8'); res.setHeader('Access-C ...

  8. 对于模块加载:ES6、CommonJS、AMD、CMD的区别

    运行和编译的概念 编译包括编译和链接两步. 编译,把源代码翻译成机器能识别的代码或者某个中间状态的语言. 比如java只有JVM识别的字节码,C#中只有CLR能识别的MSIL.还简单的作一些比如检查有 ...

  9. mybatis连接mysql查询时报Cannot convert value '0000-00-00 00:00:00' from column 10 to TIMESTAMP

    今天在学习mybatis框架的时候遇到了一个问题:查询用户表的时候报 Cannot convert value '0000-00-00 00:00:00' from column 10 to TIME ...

  10. rsync提权

    介绍:Rsync是linux下一款数据备份工具,默认开启873端口 利用条件:rsync未授权 列出模板 rsync rsync://目标ip:873/ 列出模块src下的文件 rsync rsync ...