二叉树中最长的连续序列

/*
给定一个二叉树,你需要找出二叉树中最长的连续序列路径的长度。

请注意,该路径可以是递增的或者是递减。例如,[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;

            }

        }

posted @ 2022-03-06 10:55  13917796387  阅读(350)  评论(0)    收藏  举报