LeetCode递归求二叉树公共祖先时返回数组为undefined的原因
问题原因
返回undefined和引用类型无关,核心是递归函数的返回逻辑存在漏洞:
- 你写的
findNode仅在当前节点就是目标节点时,才会显式返回路径数组 - 递归调用右、左子节点的分支,既没有接收递归调用的返回值,也没有把找到的结果向上层传递返回
- JS函数执行完所有分支都没命中
return语句时,会默认返回undefined,外层赋值自然拿不到正确的数组结果
另外你当前的路径记录逻辑还有额外bug:遍历子节点前直接把当前节点push进数组,如果走的分支找不到目标节点,没有把错误路径上的节点弹出,最终拿到的路径会掺杂大量不在根到目标链路上的无关节点。
修复代码
调整递归返回逻辑+补全路径回溯即可,对应你原有思路的可运行实现:
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @param {TreeNode} p * @param {TreeNode} q * @return {TreeNode} */ var lowestCommonAncestor = function(root, p, q) { // 查找从根节点到目标节点的完整路径 const findNode = function(currentNode, targetNode) { const path = []; const dfs = (node) => { if (!node) return false; // 当前节点先加入路径 path.push(node); // 命中目标,向上层返回命中标记 if (node.val === targetNode.val) return true; // 递归查找左右子树,任意一侧命中就直接向上返回 const foundInLeft = dfs(node.left); const foundInRight = dfs(node.right); if (foundInLeft || foundInRight) return true; // 两侧都没找到,说明当前节点不在目标路径上,弹出后回溯 path.pop(); return false; } dfs(currentNode); return path; } const pAncestors = findNode(root, p); const qAncestors = findNode(root, q); // 从头对比两条路径,最后一个相同节点就是最近公共祖先 let lowestAncestor = null; for (let i = 0; i < Math.min(pAncestors.length, qAncestors.length); i++) { if (pAncestors[i].val === qAncestors[i].val) { lowestAncestor = pAncestors[i]; } else { break; } } return lowestAncestor; };
BST特性优化写法
这道题给的是二叉搜索树,不需要专门记录完整路径,利用BST左子树所有节点值小于根、右子树所有节点值大于根的特性,一次遍历就能拿到结果,空间复杂度可以降到O(1):
- 如果当前节点值比p、q都大,说明p、q都在左子树,往左遍历
- 如果当前节点值比p、q都小,说明p、q都在右子树,往右遍历
- 剩下的情况(p、q分别在左右子树,或者当前节点就是p/q其中一个),当前节点就是最近公共祖先
var lowestCommonAncestor = function(root, p, q) { let cur = root; while (cur) { if (cur.val > p.val && cur.val > q.val) { cur = cur.left; } else if (cur.val < p.val && cur.val < q.val) { cur = cur.right; } else { return cur; } } return null; };
内容的提问来源于stack exchange,提问作者HigherOrderChilli
相关产品推荐
相关产品推荐

