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. Vue 路由守卫解决页面退出和弹窗的显示冲突

    在使用UI框架提供的弹出层Popup时,如Vant UI的popup,在弹出层显示时,点击物理按键或者小程序自带的返回时,会直接退出页面,这明显不符合页面逻辑. 解决思路: 在弹出层显示时,点击了返回 ...

  2. K-means:如何选择K(cluster的数目)

    目前决定cluster数目的常用方法是手动地决定cluster的数目 哪个K是正确的? 上图中的数据集,我们可以说它有4个clusters,也可以说它有2个clusters,但哪个是正确答案呢?其实这 ...

  3. django-改写manage类-objects

    user/models.py中 class AddressManage(models.Manager): '''地址模型管理类''' def get_default_addr(self, user): ...

  4. windows认证过程

    NTLM简介: NTLM使用在Windows NT和Windows 2000 Server(or later)工作组环境中(Kerberos用在域模式下).在AD域环境中,如果需要认证Windows ...

  5. Highcharts error #16: www.highcharts.com/errors/16 js 单例

    一.问题项目某一个页面用的highcharts用来显示一张图表,第一次刷新正常,第二次就出来这个错.1二.解决问题过程在网上找了很多同样是这个错误的解决方案. 第一:加载了highstock.js然后 ...

  6. openjdk k8s port-forward 连接容器jmx服务

    jmx 是java 自带的,如果需要使用我们只需要添加对应的配置即可,以下演示docker 集成jmx 使用kompose 生成k8s 的部署文件,使用port-forward 进行连接,所以java ...

  7. 开源项目 03 DocX

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. javascript轮询请求服务器

    抛出问题:web浏览器如何与服务保持通信? 方法一:Ajax轮询 方法二:EventSource轮询 方法三:websocket保持长连接 下面的解决方案是,Ajax轮询与EventSource轮询的 ...

  9. 稀疏矩阵的存储(c++)

    0        0        0        0        0         0 0        3        0        0        0         0 0    ...

  10. mybatis Example Criteria like 模糊查询

    用Mybatis代码生成工具会产生很多个XXXExample类,这些类的作用是什么? 查阅了很多资料,在这里总结归纳一下 简介XXXExample类用于构造复杂的筛选条件 它包含一个名为Criteri ...