繁体   English   中英

为什么在递归中使用 let replace var 更好?

[英]why use let replace var in recursion is better?

当我尝试做 LeetCode 第 25 题时,使用 var 不能通过,但使用 let 可以通过

变量

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} k
 * @return {ListNode}
 */
var reverseKGroup = function(head, k) {
    var p = head;
    var cur = head;
    var pre = null;
    for(var i=0; i< k; i++) {
        // 如果里面没走到最后就结束,则直接返回这部分链表 不需要再反转
        if(p == null) return head;
        p = p.next;
    }
    // 反转部分链表
    for(var j=0 ; i< k; i++) {
        var temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
    }
    // 此时的尾部即为一开始的头部,next 为接下来反转
    head.next = reverseKGroup(cur, k);
    return pre;
};

唯一的区别是使用“var”或“let”。

使用 var 会导致溢出。

Line 13 in solution.js
var reverseKGroup = function(head, k) {
                            ^
RangeError: Maximum call stack size exceeded

有人可以解释一下吗?

这似乎是一个错误。 (var j=0; i< k; i++) 你给j设置一个变量,然后你根据i迭代? i 仅在前面的 for 循环中声明。 如果您使用 var,则此 i 将基于第一个“i”,因为它设置为 function scope。而如果您使用 let,则不会交叉污染。 您可能应该只将第二个 for 循环更改为 (let i=0; i

超出最大调用堆栈大小 --- solution.js 中的第 13 行 有两种方法可以解决此问题。

由于某种原因,For 循环没有在第 13 行终止……好吧,终止条件是 iABOVE 在第一个 for 循环中。

这就是 let 与 const 的用武之地。

您已将第二个 for 循环中使用的 i 声明为与第一个 for 循环相同的 i(因为 var i=0)。

使用 var 立即提升变量,将其放置在全局 scope / 词法上下文中。

将 var 更改为 let在第一个循环中会导致在第二个循环的词法上下文中出现“reference i not being defined”:

在此处输入图像描述

任何时候 javascript 中的 function 执行时,它都会使用特定的“执行上下文”,其中包含词法环境/映射变量到值的上下文。

Function 执行上下文是根据它们在被调用时的位置而产生的。 在这种情况下,第二个 for 循环的执行上下文在其第一个循环中具有 i=k 的值,这是它的停止条件。

最后,在第一个循环中,如果前一个节点不是 null,则停止条件。并且由于第二个 for 循环永远不会运行(关键:它使用与第一个 for 循环相同的 i 值和相同的停止条件,)然后 reverseKGroup( cur, k) 将重复执行 cur 等于 head 的值。 只要 head 不为空,就会导致无限循环。

在此处输入图像描述

下面的代码通过了所有测试,只需在第二个循环中将 i 更改为 j:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM