Finding the Middle of a Linked List
Tags: javascript, linkedlist, algorithms, codenewbie
Published: 2020-05-17 17:52:47

A common interview problem is, given a linked list, return the node that's in the middle. If there are two "middle nodes", return the second one. (You can find this problem on Leetcode [here](https://leetcode.com/problems/middle-of-the-linked-list/).)

One approach to this problem involve iterating through the linked list, putting each node value in a new array, and then finding the middle element of the array. This approach does have a time complexity of O(n), and a space complexity of O(n), since all of the nodes are put into a new array.

How would you solve this with a space complexity of O(1)? In this post, I'll walk through a straightforward solution to this common problem. First, I'll explain how the solution works in diagrams. Then, I'll walk through how to code it out using JavaScript.

## Two Pointers: Visualization Using Diagrams

The idea behind this approach is to have two different pointers--one that is "fast" and one that is "slow". The slow pointer moves one node at a time. The fast pointer moves two nodes at a time. When the fast pointer gets to the end of the list, that's when the slow pointer will be at the middle of the list.

I originally had difficulty visualizing this, but once I drew it out with diagrams, it made a lot more sense.

Let's say you're given a linked list. The first box represents the head. You'll have two pointers, `slow` and `fast`, which both start at the head.

![Slow and fast variables initialized at the head of a linked list](https://dev-to-uploads.s3.amazonaws.com/i/r28spftlxdahquhyan1k.png)


Now, after one turn, the slow pointer will move one node, and the fast pointer will move two.

![The slow variable moved over one node, while the fast variable moved over two nodes](https://dev-to-uploads.s3.amazonaws.com/i/cz4652pocb0mq8vt7mdr.png)


The fast pointer is still not at the end of the list (which you know because node.next is not null). So, there needs to be another turn. The slow pointer again moves one node, and the faster pointer moves two.

![The fast variable reached the end of the list, and the slow variable is at the middle of the list](https://dev-to-uploads.s3.amazonaws.com/i/8f4b7byruc9izh034mur.png)

Now, the fast pointer is at the end of the linked list, and the slow pointer is at the middle of the linked list.


## Two Pointers: The Code

To write this out, we have to first initialize two variables: `fast` and `slow`. In the function, you're given the head of the linked list, so you should set both fast and slow equal to the head. (You also can assume the linked list nodes have certain properties, such that node.val is the value of the node, node.next is the next node, and node.next.next is two nodes down.)

``` javascript
function middleNode(head) {
  let fast = head;
  let slow = head;

  //...
}
```

Now, we want to create a loop for the fast and slow variables to keep changing. We want them to keep changing as long as 'fast' is not null, and as long as the next node is not null. Once fast is null and/or the next node is null, you know fast is at the end of the list, and so slow is on the middle node. Inside the while loop is where we change slow and fast. Slow will be set to equal `slow.next`, and fast will equal `fast.next.next`.

``` javascript
function middleNode(head) {
  let fast = head;
  let slow = head;

  while (fast && fast.next) {
    slow = slow.next;
    fast = fast.next.next;
  }
  //...
}
```

Once the while loop ends, you know fast made it to the end of the linked list, which means slow is at the middle of the list. Now, we can simply return the node that slow is at, and that's the end of the function.

``` javascript
function middleNode(head) {
  let fast = head;
  let slow = head;

  while (fast && fast.next) {
    slow = slow.next;
    fast = fast.next.next;
  }
  return slow;
}
```

Let me know in the comments if you have any questions or other approaches to this problem!