为何多数人不将dummyNode传入递归函数?如何实现传参写法?
为什么递归时更倾向于用上层函数变量而非参数传递?
针对你观察到的LeetCode题解里的写法,主要有这几个原因:
- 简化递归调用逻辑:如果把
prev作为参数传入递归函数,每次调用dfs都要手动传递当前的prev值,代码会多一层冗余。用上层函数的闭包变量的话,递归函数可以直接访问并更新这个值,调用时只需要传节点参数,代码更简洁。 - 维护状态的连续性:像LeetCode 530题的中序遍历,我们需要持续跟踪上一个访问的节点值。闭包变量
prev在整个递归过程中是同一个作用域下的变量,天然就能保持状态的连续,不用在每次递归调用后手动同步状态,降低出错概率。 - 降低参数复杂度:如果需要维护的状态不止一个(比如这里还有
ans),把这些状态都作为递归参数的话,函数签名会变得臃肿,逻辑也更难理清。放在上层函数里,递归函数只需要专注于遍历节点的核心逻辑。
当然可以把prev设为递归参数!
不过因为JavaScript中基本类型是按值传递的,直接传prev作为参数的话,递归内部的修改不会影响外部的变量。所以我们需要通过返回值来传递更新后的prev,同时在递归过程中计算最小差值。
修改后的代码示例:
const getMinimumDifference = function(root) { let ans = Infinity; function dfs(node, prev) { if (!node) return prev; // 先遍历左子树,更新prev为左子树最后一个节点的值 prev = dfs(node.left, prev); // 计算当前节点和上一个节点的差值 if (prev !== null) { ans = Math.min(ans, node.val - prev); } // 更新prev为当前节点的值,传递给右子树 prev = node.val; // 遍历右子树,继续更新prev return dfs(node.right, prev); } dfs(root, null); return ans; };
这个版本里,dfs函数的职责是完成遍历,并返回遍历结束后最新的prev值。每次递归调用左子树后,我们会拿到左子树遍历完的prev,再用当前节点更新差值,然后把当前节点值作为prev传给右子树,最终完成整个遍历过程。
内容的提问来源于stack exchange,提问作者Kev1n
相关产品推荐
相关产品推荐

