Middle of the Linked List
EasyPrompt
Given the head of a singly linked list, return the middle node of the linked list.
If there are two middle nodes, return the second middle node.
Example 1:
Input: head = [1,2,3,4,5]
Output: [3,4,5]
Explanation: The middle node of the list is node 3.Example 2:
Input: head = [1,2,3,4,5,6]
Output: [4,5,6]
Explanation: Since the list has two middle nodes with values 3 and 4, we return the second one.
Constraints:
- The number of nodes in the list is in the range
[1, 100]. 1 <= Node.val <= 100
Approaches
3 approaches with complexity analysis and trade-offs.
This is the most optimal approach, solving the problem in a single pass with constant space. It uses two pointers, a slow pointer and a fast pointer. The slow pointer moves one step at a time, while the fast pointer moves two steps at a time. When the fast pointer reaches the end of the list, the slow pointer will be at the middle.
Algorithm
-
- Initialize two pointers,
slowandfast, both pointing to theheadof the list.
- Initialize two pointers,
-
- Start a loop that continues as long as
fastis notnullandfast.nextis notnull.
- Start a loop that continues as long as
-
- Inside the loop:
- Move
slowone step forward:slow = slow.next. - Move
fasttwo steps forward:fast = fast.next.next.
-
- When the loop terminates, the
slowpointer will be at the middle node of the linked list.
- When the loop terminates, the
-
- Return the
slowpointer.
- Return the
Walkthrough
This classic algorithm, often called the 'Tortoise and Hare' algorithm, is highly efficient for finding the middle of a linked list. The intuition is that by the time the fast pointer (hare) reaches the end of the race (the end of the list), the slow pointer (tortoise) will have covered exactly half the distance and will be at the midpoint.
We initialize both slow and fast pointers to the head of the list. Then, we enter a loop that continues as long as fast and fast.next are not null. Inside the loop, we advance slow by one node (slow = slow.next) and fast by two nodes (fast = fast.next.next).
Let's trace this for both odd and even length lists:
- Odd length (e.g.,
[1,2,3,4,5]):- Initial:
slowat 1,fastat 1. - Step 1:
slowat 2,fastat 3. - Step 2:
slowat 3,fastat 5. - Now,
fast.nextisnull. The loop terminates.slowis at node3, which is the middle.
- Initial:
- Even length (e.g.,
[1,2,3,4,5,6]):- Initial:
slowat 1,fastat 1. - Step 1:
slowat 2,fastat 3. - Step 2:
slowat 3,fastat 5. - Step 3:
slowat 4,fastbecomesnull(sincefast.nextwas 6,fast.next.nextisnull). - The loop terminates.
slowis at node4, which is the second middle node, as required.
- Initial:
This single-pass approach is both time and space efficient.
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */class Solution { public ListNode middleNode(ListNode head) { ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } return slow; }}Complexity
Time
O(N), where N is the number of nodes. Although it's O(N), it's more efficient than the two-pass approach as it only traverses the list once. The `slow` pointer makes N/2 moves.
Space
O(1), as it only uses two extra pointers, regardless of the list's size.
Trade-offs
Pros
Most efficient solution in terms of both time (single pass) and space (constant).
Elegant and a common pattern for solving linked list problems.
Cons
The logic might be slightly less intuitive for beginners compared to the counting approach.
Solutions
Solution
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode middleNode ( ListNode head ) { ListNode slow = head , fast = head ; while ( fast != null && fast . next != null ) { slow = slow . next ; fast = fast . next . next ; } return slow ; } }Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.