206. Reverse Linked Lists

Description of the Problem

Given the head of a singly linked list, reverse the list, and return the reversed list.

Example 1:

Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]

Example 2:

Input: head = [1,2]
Output: [2,1]

Example 3:

Input: head = []
Output: []

Constraints:

  • The number of nodes in the list is the range [0, 5000].
  • -5000 <= Node.val <= 5000

Solution

Tags: Rust LinkedList

Explanation

The following (Rust) code can be verified by the loop invariant

Invariant: All nodes before the current node are properly reversed

Proof:

  • Initialisation: Before the begin of the loop, No node is before the current node, the invariant is vacuously true
  • Maintenance: Suppose the invariant is true before an iteration, having perform re-ordering operations, all nodes before the current node (originally it is next node) is properly reversed
  • Termination: After all iterations, all nodes in the LinkedList are reversed properly

Code (Rust)

// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Clone, Debug)]
// pub struct ListNode {
//   pub val: i32,
//   pub next: Option<Box<ListNode>>
// }
// 
// impl ListNode {
//   #[inline]
//   fn new(val: i32) -> Self {
//     ListNode {
//       next: None,
//       val
//     }
//   }
// }


impl Solution {
    pub fn reverse_list(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        let mut curr = head;
        let mut prev = None;

        while let Some(mut node) = curr.take() {
            curr = node.next; // Transfer the ownership of node.next to curr, node.next becomes None
            node.next = prev; // The next node of the current node should point to previous node
            prev = Some(node); // Current nodebecomes preivous node for next iteration
        }

        return prev;
    }
}

Code(Java)

public class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;

        while(curr != null){
            ListNode temp = curr;
            curr = temp.next;
            temp.next = prev;
            prev= temp;
        }

        return prev;
    }
}

Code(C++)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode * prev = nullptr;
        ListNode * curr = head;
        ListNode * node;
        while( (node = curr) != nullptr ){
            curr = node->next;
            node->next = prev;
            prev = node;
        }
        return prev;
    }
};

Complexity

Time complexity:

  • \( T(n) = \mathcal{\Theta}(n) \)
    • Traversal of all nodes in LinkedList

Auxiliary Space:

  • \( S(n) = O(1) \)