-1

when i try to do a LeetCode question # 25, use var can't pass, but use let can pass

var

/**
 * 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;
};

the only difference is use "var" or "let".

use var will cause an overflow.

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

can somebody explain this ?

siyao dai
  • 7
  • 1
  • you can refer to this for long answer: [let vs var](https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var), its basically about variables scope and how javascript will access those variables defined `var` make your variables global, and `let` make them local to the scope they are in. – ROOT May 16 '20 at 05:39
  • 4
    @ROOT `var` doesn't make them global. `var` is local to the function, `let` is local to the block. – Barmar May 16 '20 at 05:41
  • @Barmar, I miss used my words here. – ROOT May 16 '20 at 05:42
  • 1
    Which variables did you have to declare with `let` to make it work? All of them? – Barmar May 16 '20 at 05:45
  • Does this answer your question? [What's the difference between using "let" and "var"?](https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var) – pensum May 16 '20 at 05:49
  • 2
    Do you have sample input and expected output? A minimal example is fine. There is weirdness in the reuse of i in `for(var i=0; i< k; i++) {...} for(var j=0 ; i< k; i++) {...}` as i is not declared in the second loop. – RobG May 16 '20 at 05:54

2 Answers2

0

This seems to be a mistake here. (var j=0 ; i< k; i++) You set a variable for j, then you iterate based on i? i is only declared in the previous for loop. If you use var, this i will be based on the first 'i' since it's set to the function scope. While if you used let, it wouldn't cross contaminate. You should probably just change the second for loop to have (let i=0; i

Andre Thompson
  • 300
  • 2
  • 9
  • That's probably the issue but it doesn't explain the range error, or why the code works at all with *let*. That might be related to the environment the code is executed in. – RobG May 16 '20 at 08:44
0

Maximum Call Stack Size Exceeded --- Line 13 in solution.js There are two ways to fix this.

The For loop doesn't get terminated on line 13 for some reason...Well, the terminating condition is when iABOVE in the first for loop.

Here's where the let vs. const comes in.

You've declared the i that's used in the second for loop as being the same i as the first for loop (as var i=0).

Using var immediately hoists the variable, placing it in the global scope / lexical context.

Changing the var to let in the first loop results in "reference i not being defined" in the second loop's lexical context:

enter image description here

Anytime a function in javascript executes, it does with a particular "execution context" which contains a lexical environment/context of mapped variables to values.

Function execution contexts are born based on their location at the time of being called. In this case, the execution context of the second for loop has the value of i=k on its first loop, which is its stopping condition.

Finally, inside the first loop, the stopping condition is if the previous node was not null. And since the second for loop never runs (key: it's using the same i value and same stopping condition as the first for loop!) then reverseKGroup(cur, k) will repeatedly execute with a value of cur equal to head, leading to infinite loop whenever head is not null.

enter image description here

The code below passes all tests, just change the i's to j's in the second loop:

JoeShmoh
  • 14
  • 3
  • 1
    The OP declares *i* once, there is no need to declare it again within the function. Multiple declarations of *i* with *var* have no impact since variable declarations are processed before any code is executed. With *var*, the second loop will never run since `i < k` has already failed from the first loop and *i* is not reset. If declarations are changed to *let*, I'd expect the second loop to throw a reference error at either `i < k` or `i++` since *i* hasn't been declared in that block or further up the scope chain (unless it's coming from somewhere not shown). – RobG May 16 '20 at 08:42
  • @RobG Clarification: "change the i's to j's" was referring to second for loop's stopping condition "i" and the iterator "i++" . I think there may have been confusion on that note. – JoeShmoh May 17 '20 at 04:40
  • Re "multiple declarations of var have no impact" yep and I hope the answer didn't seem to imply that. The problem was precisely because it makes no sense to have the second loop's stopping condition match the first loop's...Hence the swap from i's to j's. That said --- how does my answer differ from what you're saying about the stopping condition exactly? Cheers. – JoeShmoh May 17 '20 at 04:47