当前位置: 面试刷题>> 二叉树的最长连续子序列Ⅱ (经典算法题500道)


### 题目描述补充 题目:**二叉树的最长连续子序列 II** 给定一个二叉树,每个节点上都有一个整数值。我们需要找到这棵树中所有可能的连续子序列(不要求是树的子树),并返回这些连续子序列中的最长长度。这里的连续子序列指的是,从根节点开始,可以经过任意节点恰好一次(也可以不经过某些节点),路径上节点的值按顺序排列构成一个递增序列。 **注意**:与普通的路径问题不同,这里的连续子序列允许“跳跃”某些节点,只要保证路径上的值是递增的即可。 ### 示例 给定二叉树如下: ``` 3 / \ 2 4 / / \ 1 3 5 ``` 最长连续子序列为 `1 -> 2 -> 3 -> 4 -> 5`,因此返回长度为 `5`。 ### PHP 示例代码 由于 PHP 处理树形结构较为复杂且没有直接的数据结构支持,这里提供一个概念性的思路,实际实现可能需要更多细节处理。 ```php class TreeNode { public $val; public $left; public $right; function __construct($val = 0, $left = null, $right = null) { $this->val = $val; $this->left = $left; $this->right = $right; } } function longestIncreasingSubsequenceII($root) { $maxLength = 0; dfs($root, PHP_INT_MIN, 1, $maxLength); return $maxLength; } function dfs($node, $prevVal, $currentLength, &$maxLength) { if ($node == null) return; if ($node->val > $prevVal) { $currentLength++; $maxLength = max($maxLength, $currentLength); } else { $currentLength = 1; } $prevVal = $node->val; dfs($node->left, $prevVal, $currentLength, $maxLength); dfs($node->right, $prevVal, $currentLength, $maxLength); // 回溯,但由于 PHP 变量传递是按值传递,这里不需要显式回溯 currentLength } // 注意:上面的代码只是展示了递归遍历树和比较值的逻辑,并没有直接处理“跳跃”节点的情况。 // 完整处理“跳跃”需要更复杂的状态记录或使用其他数据结构(如动态规划表)。 ``` ### Python 示例代码 Python 实现通常更直观,但处理“跳跃”仍然需要额外逻辑或数据结构。 ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def longestIncreasingSubsequenceII(root): def dfs(node, prev, dp): if not node: return 0 if node.val > prev: # 尝试通过当前节点继续递增 dp[node.val] = max(dp.get(node.val, 1), dp[prev] + 1) # 递归左右子树,不限制必须递增 dfs(node.left, node.val, dp) dfs(node.right, node.val, dp) return dp # 初始化 dp 为空字典,或使用默认值 {None: 0} 来处理边界情况 dp = {} dfs(root, float('-inf'), dp) return max(dp.values(), default=0) # 注意:这里的实现简化了问题,实际上可能还需要进一步处理来确保“跳跃”的正确性。 ``` ### JavaScript 示例代码 ```javascript function TreeNode(val, left, right) { this.val = (val===undefined ? 0 : val) this.left = (left===undefined ? null : left) this.right = (right===undefined ? null : right) } function longestIncreasingSubsequenceII(root) { let maxLength = 0; let dp = new Map(); function dfs(node, prev) { if (!node) return 0; let currentLength = 0; if (node.val > prev) { currentLength = dp.get(prev) + 1; dp.set(node.val, currentLength); maxLength = Math.max(maxLength, currentLength); } else { dp.set(node.val, 1); } dfs(node.left, node.val); dfs(node.right, node.val); } dfs(root, -Infinity); return maxLength; } // 注意:JavaScript 示例同样简化了问题,实际处理“跳跃”需要更复杂的设计。 ``` **码小课**:以上代码和思路提供了一个基本的框架,但在处理“跳跃”节点以形成最长连续递增子序列时可能需要进一步的设计和优化。在码小课网站上,你可以找到更多关于树形数据结构、动态规划、递归等算法的深入解析和实战练习,帮助你更好地理解和掌握这类问题。
推荐面试题