# Question

Formatted question description: https://leetcode.ca/all/298.html

Given the root of a binary tree, return the length of the longest consecutive sequence path.

A consecutive sequence path is a path where the values increase by one along the path.

Note that the path can start at any node in the tree, and you cannot go from a node to its parent in the path.

Example 1:

Input: root = [1,null,3,2,4,null,null,null,5]
Output: 3
Explanation: Longest consecutive sequence path is 3-4-5, so return 3.


Example 2:

Input: root = [2,null,3,2,null,1]
Output: 2
Explanation: Longest consecutive sequence path is 2-3, not 3-2-1, so return 2.


Constraints:

• The number of nodes in the tree is in the range [1, 3 * 104].
• -3 * 104 <= Node.val <= 3 * 104

# Algorithm

If the left child node exists and the node value is greater than the value of its parent node by 1, the function is called recursively.

If the node value is not exactly greater than 1, the function with the length reset is recursively called. The processing of the right child node and the left child node the same.

# Code

• 
public class Binary_Tree_Longest_Consecutive_Sequence {
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {

private int maxLen = 0;

public int longestConsecutive(TreeNode root) {
longestConsecutive(root, 0, 0);
return maxLen;
}

private void longestConsecutive(TreeNode root, int lastVal, int curLen) {
if (root == null) {
return;
}
if (root.val != lastVal + 1) {
curLen = 1;
} else {
curLen++;
}

maxLen = Math.max(maxLen, curLen);

longestConsecutive(root.left, root.val, curLen);
longestConsecutive(root.right, root.val, curLen);
}
}

// Top-down DFS
class Solution_topdown {
public int longestConsecutive(TreeNode root) {
return getLongestConsecutive(root, null, 0);
}

private int getLongestConsecutive(TreeNode child, TreeNode parent, int len) {
if (child == null) return 0;
len = (parent != null && parent.val == child.val - 1) ? len + 1 : 1;
return Math.max(len,
Math.max(
getLongestConsecutive(child.left, child, len),
getLongestConsecutive(child.right, child, len)
)
);
}
}

// Bottom-up DFS
public class Solution_bottomUp {

int result = 0;
public int longestConsecutive(TreeNode root) {
if (root == null) {
return 0;
}
getLongestConsecutive(root);
return result;
}

private int getLongestConsecutive(TreeNode root) {
int ret = 1;

if (root.left != null) {
int left = getLongestConsecutive(root.left);
if (root.val == root.left.val - 1) {
ret = Math.max(ret, 1 + left);
}
}

if (root.right != null) {
int right = getLongestConsecutive(root.right);
if (root.val == root.right.val - 1) {
ret = Math.max(ret, 1 + right);
}
}

result = Math.max(result, ret);
return ret;
}

}
}

############

/**
* Definition for a binary tree node.
* public class TreeNode {
*     int val;
*     TreeNode left;
*     TreeNode right;
*     TreeNode() {}
*     TreeNode(int val) { this.val = val; }
*     TreeNode(int val, TreeNode left, TreeNode right) {
*         this.val = val;
*         this.left = left;
*         this.right = right;
*     }
* }
*/
class Solution {
private int ans;

public int longestConsecutive(TreeNode root) {
ans = 1;
dfs(root, null, 1);
return ans;
}

private void dfs(TreeNode root, TreeNode p, int t) {
if (root == null) {
return;
}
t = p != null && p.val + 1 == root.val ? t + 1 : 1;
ans = Math.max(ans, t);
dfs(root.left, root, t);
dfs(root.right, root, t);
}
}

• // OJ: https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/
// Time: O(N)
// Space: O(H)
class Solution {
int ans = 0;
void dfs(TreeNode *root, TreeNode *parent = NULL, int length = 1) {
if (!root) return;
length = parent && parent->val + 1 == root->val ? length + 1 : 1;
ans = max(ans, length);
dfs(root->left, root, length);
dfs(root->right, root, length);
}
public:
int longestConsecutive(TreeNode* root) {
dfs(root);
return ans;
}
};

• # Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
def longestConsecutive(self, root: TreeNode) -> int:
maxLen = 0

# curLen: consecutive length until parent node
def dfs(root: TreeNode, lastVal: int, curLen: int) -> None:
nonlocal maxLen
if not root:
return

curLen = (curLen + 1) if (not lastVal) and root.val == lastVal + 1 else 1
maxLen = max(maxLen, curLen)

dfs(root.left, root.val, curLen)
dfs(root.right, root.val, curLen)

dfs(root, None, 0)
return maxLen

############

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
def longestConsecutive(self, root):
"""
:type root: TreeNode
:rtype: int
"""

def helper(root):
if not root:
return (None, 0, 0)  # (val, consecutive len, max consecutive len)
left, leftLen, maxLeftLen = helper(root.left)
right, rightLen, maxRightLen = helper(root.right)
ret = 1
if root.val + 1 == left:
ret = leftLen + 1
if root.val + 1 == right:
ret = max(ret, rightLen + 1)
return (root.val, ret, max(maxLeftLen, maxRightLen, ret))

return helper(root)[2]


• /**
* Definition for a binary tree node.
* type TreeNode struct {
*     Val int
*     Left *TreeNode
*     Right *TreeNode
* }
*/
func longestConsecutive(root *TreeNode) int {
ans := 1
var dfs func(root, p *TreeNode, t int)
dfs = func(root, p *TreeNode, t int) {
if root == nil {
return
}
if p != nil && p.Val+1 == root.Val {
t++
ans = max(ans, t)
} else {
t = 1
}
dfs(root.Left, root, t)
dfs(root.Right, root, t)
}
dfs(root, nil, 1)
return ans
}

func max(a, b int) int {
if a > b {
return a
}
return b
}

• /**
* Definition for a binary tree node.
* class TreeNode {
*     val: number
*     left: TreeNode | null
*     right: TreeNode | null
*     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
*         this.val = (val===undefined ? 0 : val)
*         this.left = (left===undefined ? null : left)
*         this.right = (right===undefined ? null : right)
*     }
* }
*/

function longestConsecutive(root: TreeNode | null): number {
let ans = 0;
const dfs = (root: TreeNode | null): number => {
if (root === null) {
return 0;
}
let l = dfs(root.left) + 1;
let r = dfs(root.right) + 1;
if (root.left && root.left.val - root.val !== 1) {
l = 1;
}
if (root.right && root.right.val - root.val !== 1) {
r = 1;
}
const t = Math.max(l, r);
ans = Math.max(ans, t);
return t;
};
dfs(root);
return ans;
}