strategies to reverse a linked list in JavaScript

后端 未结 6 1357
一个人的身影
一个人的身影 2020-12-13 20:23

I just struggled through a simple interview question: Please reverse a singly linked list.

While I failed to provide a working answer in time to save the interview,

相关标签:
6条回答
  • 2020-12-13 20:34

    ES6 solution: Just keep a track of the reversed list and keep adding that to tmp.

    const reverseLinkedList = (head) => {
      let reversed = null;
      while(head) {
        const tmp = head;
        head = head.next;
        tmp.next = reversed;
        reversed = tmp;
      }
    
      return reversed;
    };
    
    console.log(JSON.stringify(reverseLinkedList({
      data: 1,
      next: {
        data: 2,
        next: {
          data: 3,
          next: {
            data: 4,
            next: {
              data: 5,
              next: {
                data: 5,
                next: {
                  data: 6
                }
              }
            }
          }
        }
      }
    })));
    
    0 讨论(0)
  • 2020-12-13 20:35

    This would be O(n) in time, since you do a constant number of operations on each node. Conceptually, there isn't a more efficient way of doing things (in terms of big-O notation, there's some code optimization that could be done.)

    The reason why you can't exceed O(n) is because, in order to do so, you would need to skip some nodes. Since you need to modify each node, this wouldn't be possible.

    Efficiency then comes down to a constant factor. The fewer operations you can do per item in the list, the faster your code will execute.

    I'd implement like this:

    function reverseLinkedList(list, previous){
    
      //We need to use the the current setting of
      //list.next before we change it. We could save it in a temp variable,
      //or, we could call reverseLinkedList recursively
      if(list.next !== null){
        reverseLinkedList(list.next, list);
      }
    
      //Everything after 'list' is now reversed, so we don't need list.next anymore.
      //We passed previous in as an argument, so we can go ahead and set next to that.
      list.next = previous;
    }
    
    reverseLinkedList(list, null);
    

    Of course, this is recursive, so it would be inefficient in terms of space, but I like recursive code :)

    This also doesn't return the reversed linked list, but we could fairly easily modify things to do so if that were important.

    0 讨论(0)
  • 2020-12-13 20:35

    Reversing the SinglyLinkedList: Input: 1->2->3->4->5->NULL Output: 5->4->3->2->1->NULL

    To understand The Solution we have to keep track of previous head and next variables for example in above input Head = 1 ; next = 2 we don't have previous so assume previous = null loop the list till head is not null. reverse the connections(previous and next) of head. Below is the code

    var reverseList = function(head) {
        let previous = null;
        while(head !== null){
            let next = head.next;
            head.next = previous;
            previous= head
            head = next;
        }
        return previous;
        
    };

    0 讨论(0)
  • 2020-12-13 20:44

    There are a couple of problems with your code. This should make it clear.

    // reverse a linked list  
    var reverseLinkedList = function(linkedlist) {
      var node = linkedlist;
      var previous = null;
    
      while(node) {
        // save next or you lose it!!!
        var save = node.next;
        // reverse pointer
        node.next = previous;
        // increment previous to current node
        previous = node;
        // increment node to next node or null at end of list
        node = save;
      }
      return previous;   // Change the list head !!!
    }
    linkedlist = reverseLinkedList(linkedlist);
    
    0 讨论(0)
  • You could solve this problem recursively in O(n) time as ckersch mentions. The thing is, that you need to know that recursion is memory intensive since functions accumulate in the calls stack until they hit the stop condition and start returning actual things.

    The way I'd solve this problem is:

     const reverse = (head) => {
       if (!head || !head.next) {
         return head;
       }
       let temp = reverse(head.next);
       head.next.next = head;
       head.next = undefined;
       return temp;
     }    
    

    When reverse() reaches the end of the list, it will grab the last node as the new head and reference each node backwards.

    0 讨论(0)
  • 2020-12-13 20:48

    //O(n) | O(1) wherre n is the number of nodes in the linked list
    
    class Node{
      constructor(val){
        this.val = val;
        this.next = null;
      }
    }
    
    
    function reverseLinkedList(head) {
    
     if(!head) return null;
     
     let p1 = head;
     let p2 = null;
    	
    	while(p1){
    		let temp = p1.next;
    		p1.next = p2;
    		p2 = p1;
    		p1 = temp;
    	}
    	
    	return p2;
    }
    
    
    const a = new Node(1);
    a.next = new Node(2);
    a.next.next = new Node(3)
    
    console.log("Current Node",a);
    console.log("Reversed List",reverseLinkedList(a))

    0 讨论(0)
提交回复
热议问题