skip to Main Content

I encountered some strange destructuring behavior when reversing a linked list in this problem:

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    let previous = null
    while (head) {

        // Version 1 - works
        [head.next, head, previous] = [previous, head.next, head]

        // Version 2 - doesn't work
        // [previous, head, head.next] = [head, head.next, previous]

        // Version 3 - doesn't work
        // [head, head.next, previous] = [head.next, previous, head]

    }
    return previous
};

I cannot for the life of me figure out why destructing assignments v2 and v3 don’t work while version 1 does. The head.next assignment is causing the problem. The error is:

Line 16 in solution.js
        [previous, head, head.next] = [head, head.next, previous]
                              ^
TypeError: Cannot set properties of null (setting 'next')

Can someone explain way version 1 works and versions 2 and 3 do not?

2

Answers


  1. It’s easier to see the difference if you break up the destructuring into separate assignments.

    Version 1 is equivalent to:

    let temp = [previous, head.next, head]
    head.next = temp[0];
    head = temp[1];
    previous = temp[2];
    

    Version 2 is equivalent to:

    let temp = [head, head.next, previous]
    previous = temp[0];
    head = temp[1];
    head.next = temp[2];
    

    And version 3:

    let temp = [head.next, previous, head]
    head = temp[0];
    head.next = temp[1];
    previous = temp[2];
    

    In versions 2 and 3 you’re assigning head.next after you’ve reassigned head = head.next. But you need to change the next property of the original head node, not the new one.

    And if the original head.next was null, you’ll get an error when you try to assign head.next after the assignment, because you can’t set properties of null.

    Login or Signup to reply.
  2. JavaScript is destructuring the array one by one. Version 2 gives you an error because JavaScript does this:

    // What you see:
    [previous, head, head.next] = [head, head.next, previous]
    
    // What the compiler sees:
    previous = head;
    head = head.next; // What is head.next? It hasn't been defined! throw TypeError
    head.next = previous; // [JavaScript never gets here since there was an error]
    

    Hence why only the first solution works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search