二叉树中最长的连续序列
/*
给定一个二叉树,你需要找出二叉树中最长的连续序列路径的长度。
请注意,该路径可以是递增的或者是递减。例如,[1,2,3,4] 和 [4,3,2,1] 都被认为是合法的,而路径 [1,2,4,3] 则不合法。另一方面,路径可以是 子-父-子 顺序,并不一定是 父-子 顺序。
示例 1:
输入:
1
/ \
2 3
输出: 2
解释: 最长的连续路径是 [1, 2] 或者 [2, 1]。
示例 2:
输入:
2
/ \
1 3
输出: 3
解释: 最长的连续路径是 [1, 2, 3] 或者 [3, 2, 1]。
注意: 树上所有节点的值都在 [-1e7, 1e7] 范围内。
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/dfs/eqzaic/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/
/*后序遍历 + 回溯 + 深度优先 + 递归 + 动态规划,即树形动态规划。
方法一重点:返回根节点到左子树及右子树的最长连续升序及降序序列的长度,答案是ans = Math.Max(ans, dcr + inr - 1)
方法二重点:返回一个包含5个元素的数组
第0个元素表示根节点到左右子树的最长连续序列的长度
第1个元素表示左子树最长连续序列的长度
第2个元素表示右子树最长连续序列的长度
第3个元素表示根节点到左子树是升序,还是降序,有三个状态:0表示其它,1表示降序,2表示升序
第4个元素表示根节点到右子树是升序,还是降序。
*/
public class LongestConsecutiveSolutionV2
{
int ans = 0;
public int LongestConsecutive(TreeNode root)
{
if (root == null)
return ans;
//DFSV2(root);
DFS(root);
return ans;
}
public int[] DFS(TreeNode root)
{
if (root == null)
return new int[] { 0, 0 };
int inr = 1, dcr = 1;
int[] l = DFS(root.left);
if (root.val == root.left?.val + 1)
dcr = l[1] + 1;
else if (root.val == root.left?.val - 1)
inr = l[0] + 1;
int[] r = DFS(root.right);
if (root.val == root.right?.val + 1)
dcr = Math.Max(dcr, r[1] + 1);
else if (root.val == root.right?.val - 1)
inr = Math.Max(inr, r[0] + 1);
ans = Math.Max(ans, dcr + inr - 1);
return new int[] { inr, dcr };
}
private int[] DFSV2(TreeNode root)
{
int[] res = new int[] { 0, 0, 0, 0, 0 };
if (root == null)
return res;
var left = DFSV2(root.left);
var right = DFSV2(root.right);
res[0] = 1;
if (left[0] > 0)
{
res[1] = 1;
if (root.left.val == root.val + 1)
{
if (left[1] > 0 && left[3] == 2)
res[1] += left[1];
if (left[2] > 0 && left[4] == 2)
res[1] = Math.Max(res[1], 1 + left[2]);
res[3] = 2;
res[0] = Math.Max(res[0], res[1] + 1);
}
else if (root.left.val == root.val - 1)
{
if (left[1] > 0 && left[3] == 1)
res[1] += left[1];
if (left[2] > 0 && left[4] == 1)
res[1] = Math.Max(res[1], 1 + left[2]);
res[3] = 1;
res[0] = Math.Max(res[0], res[1] + 1);
}
}
if (right[0] > 0)
{
res[2] = 1;
if (root.right.val == root.val + 1)
{
if (right[1] > 0 && right[3] == 2)
res[2] += right[1];
if (right[2] > 0 && right[4] == 2)
res[2] = Math.Max(res[2], 1 + right[2]);
res[4] = 2;
res[0] = Math.Max(res[0], res[2] + 1);
}
else if (root.right.val == root.val - 1)
{
if (right[1] > 0 && right[3] == 1)
res[2] += right[1];
if (right[2] > 0 && right[4] == 1)
res[2] = Math.Max(res[2], 1 + right[2]);
res[4] = 1;
res[0] = Math.Max(res[0], res[2] + 1);
}
}
ans = Math.Max(ans, Math.Max(res[1], res[2]));
ans = Math.Max(ans, res[0]);
if ((res[3] == 1 && res[4] == 2) || (res[3] == 2 && res[4] == 1))
ans = Math.Max(ans, res[1] + res[2] + 1);
return res;
}
}

浙公网安备 33010602011771号