328. Odd Even Linked List
Problem Description
You are given the head of a singly linked list. Your task is to reorganize the list by grouping all nodes at odd positions together, followed by all nodes at even positions, and return the reordered list.
The position counting starts from 1, so:
- The 1st node (position 1) is considered odd
 - The 2nd node (position 2) is considered even
 - The 3rd node (position 3) is considered odd
 - And so on...
 
The key requirements are:
- Maintain the relative order within each group (odd nodes stay in their original order relative to each other, same for even nodes)
 - Use 
O(1)extra space (modify the list in-place without creating new nodes) - Achieve 
O(n)time complexity (single pass through the list) 
For example, if the input list is 1 -> 2 -> 3 -> 4 -> 5:
- Odd position nodes: 1 (pos 1), 3 (pos 3), 5 (pos 5)
 - Even position nodes: 2 (pos 2), 4 (pos 4)
 - Output: 
1 -> 3 -> 5 -> 2 -> 4 
The solution uses two pointers to track the tail of odd and even sublists separately. As we traverse the list, we alternately append nodes to the odd and even sublists. Finally, we connect the tail of the odd sublist to the head of the even sublist to form the complete reordered list.
Intuition
The key insight is that we need to separate the linked list into two sublists - one containing nodes at odd positions and another containing nodes at even positions - then connect them together.
Since we need O(1) space, we cannot create new nodes or use additional data structures. We must rearrange the existing nodes by modifying their pointers.
Think of it like dealing cards into two piles alternately. If we have cards numbered 1, 2, 3, 4, 5, we'd deal them as:
- Pile 1 (odd): 1, 3, 5
 - Pile 2 (even): 2, 4
 
The challenge is doing this with a linked list where we can only access nodes sequentially.
The natural approach is to maintain two separate chains while traversing:
- An "odd chain" that links all odd-positioned nodes
 - An "even chain" that links all even-positioned nodes
 
As we traverse the original list, we can "pluck out" nodes and attach them to their respective chains. We need:
- Pointer 
ato track the tail of the odd chain - Pointer 
bto track the tail of the even chain - Pointer 
cto remember the head of the even chain (so we can connect it to the odd chain's tail at the end) 
The pattern emerges: starting from the first node (odd), we alternately redirect pointers:
- Connect current odd node to the next odd node (skipping the even one in between)
 - Connect current even node to the next even node (skipping the odd one in between)
 
This way, we're essentially "unweaving" the original list into two separate strands, then joining them end-to-end. The beauty is that this maintains the relative order within each group naturally, since we're processing nodes in their original sequence.
Solution Approach
Let's walk through the implementation step by step using the two-pointer technique to separate odd and even positioned nodes.
Initial Setup:
- First, handle the edge case: if 
headisNone, returnNone - Set pointer 
ato point to the first node (head) - this will track the tail of odd nodes - Set pointer 
bto point to the second node (head.next) - this will track the tail of even nodes - Save pointer 
cpointing tohead.next- this preserves the head of the even nodes list for later connection 
Main Loop:
The loop continues while b and b.next exist. The condition b and b.next ensures we have enough nodes to continue the rewiring process.
In each iteration:
- 
Connect odd nodes:
a.next = b.next- Make the current odd node point to the next odd node (skipping the even node in between)a = a.next- Move the odd pointer forward to the newly connected node
 - 
Connect even nodes:
b.next = a.next- Make the current even node point to the next even node (after the odd node we just moved to)b = b.next- Move the even pointer forward to the newly connected node
 
Example walkthrough with list 1 -> 2 -> 3 -> 4 -> 5:
Initial state:
apoints to node 1,bpoints to node 2,cpoints to node 2
Iteration 1:
a.next = b.next→ Node 1 now points to node 3a = a.next→amoves to node 3b.next = a.next→ Node 2 now points to node 4b = b.next→bmoves to node 4
Iteration 2:
a.next = b.next→ Node 3 now points to node 5a = a.next→amoves to node 5b.next = a.next→ Node 4 now points toNone(end of list)b = b.next→bbecomesNone
Loop ends as b is None.
Final Connection:
a.next = c- Connect the tail of the odd list (node 5) to the head of the even list (node 2)- Return 
headwhich still points to node 1 
The final list structure is: 1 -> 3 -> 5 -> 2 -> 4
Time and Space Complexity:
- Time: 
O(n)- We traverse the list once - Space: 
O(1)- We only use a constant number of pointers 
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's trace through the algorithm with a simple example: 1 -> 2 -> 3 -> 4
Initial Setup:
Original: 1 -> 2 -> 3 -> 4 ↑ ↑ a b,c
apoints to node 1 (tracks odd nodes)bpoints to node 2 (tracks even nodes)csaves node 2 (head of even list)
Iteration 1:
Step 1: Connect odd nodes
a.next = b.next // Node 1 points to node 3 1 -----> 3 -> 4 2 ↗
Step 2: Move a forward
a = a.next // a moves to node 3 1 -> 3 -> 4 ↑ a
Step 3: Connect even nodes
b.next = a.next // Node 2 points to node 4 Odd chain: 1 -> 3 Even chain: 2 -> 4
Step 4: Move b forward
b = b.next // b moves to node 4 Even chain: 2 -> 4 ↑ b
Check loop condition: b exists (node 4) but b.next is None, so loop ends.
Final Connection:
a.next = c // Connect node 3 to node 2 Result: 1 -> 3 -> 2 -> 4
The nodes have been successfully reorganized with odd positions (1st and 3rd) followed by even positions (2nd and 4th), maintaining their relative order within each group.
Solution Implementation
1# Definition for singly-linked list.
2# class ListNode:
3#     def __init__(self, val=0, next=None):
4#         self.val = val
5#         self.next = next
6
7from typing import Optional
8
9class Solution:
10    def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
11        """
12        Rearrange a linked list so that all odd-indexed nodes come first,
13        followed by all even-indexed nodes (1-indexed).
14      
15        Args:
16            head: The head of the input linked list
17          
18        Returns:
19            The head of the rearranged linked list
20        """
21        # Handle empty list
22        if head is None:
23            return None
24      
25        # Initialize pointers for odd and even lists
26        odd_current = head                    # Pointer to traverse odd nodes
27        even_head = head.next                 # Store the head of even list for later connection
28        even_current = head.next              # Pointer to traverse even nodes
29      
30        # Traverse the list and separate odd and even nodes
31        while even_current and even_current.next:
32            # Connect current odd node to next odd node
33            odd_current.next = even_current.next
34            odd_current = odd_current.next
35          
36            # Connect current even node to next even node
37            even_current.next = odd_current.next
38            even_current = even_current.next
39      
40        # Connect the end of odd list to the head of even list
41        odd_current.next = even_head
42      
43        return head
441/**
2 * Definition for singly-linked list.
3 * public class ListNode {
4 *     int val;
5 *     ListNode next;
6 *     ListNode() {}
7 *     ListNode(int val) { this.val = val; }
8 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
9 * }
10 */
11class Solution {
12    public ListNode oddEvenList(ListNode head) {
13        // Handle edge case: empty list
14        if (head == null) {
15            return null;
16        }
17      
18        // Initialize pointers for odd and even nodes
19        ListNode oddCurrent = head;           // Pointer to traverse odd-indexed nodes
20        ListNode evenCurrent = head.next;     // Pointer to traverse even-indexed nodes
21        ListNode evenHead = evenCurrent;      // Save the head of even list for later connection
22      
23        // Rearrange nodes by alternating odd and even indexed nodes
24        // Continue while there are even nodes and nodes after even nodes
25        while (evenCurrent != null && evenCurrent.next != null) {
26            // Connect current odd node to the next odd node (skip even node)
27            oddCurrent.next = evenCurrent.next;
28            oddCurrent = oddCurrent.next;
29          
30            // Connect current even node to the next even node (skip odd node)
31            evenCurrent.next = oddCurrent.next;
32            evenCurrent = evenCurrent.next;
33        }
34      
35        // Connect the tail of odd list to the head of even list
36        oddCurrent.next = evenHead;
37      
38        return head;
39    }
40}
411/**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 *     int val;
5 *     ListNode *next;
6 *     ListNode() : val(0), next(nullptr) {}
7 *     ListNode(int x) : val(x), next(nullptr) {}
8 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
9 * };
10 */
11class Solution {
12public:
13    ListNode* oddEvenList(ListNode* head) {
14        // Handle empty list
15        if (!head) {
16            return nullptr;
17        }
18      
19        // Initialize pointers for odd and even nodes
20        ListNode* oddCurrent = head;                    // Current odd position node
21        ListNode* evenCurrent = head->next;             // Current even position node
22        ListNode* evenHead = evenCurrent;               // Save the head of even list for later connection
23      
24        // Rearrange nodes by alternating odd and even positions
25        // Continue while there are even nodes and nodes after them
26        while (evenCurrent && evenCurrent->next) {
27            // Connect current odd node to the next odd node (skip even node)
28            oddCurrent->next = evenCurrent->next;
29            oddCurrent = oddCurrent->next;
30          
31            // Connect current even node to the next even node (skip odd node)
32            evenCurrent->next = oddCurrent->next;
33            evenCurrent = evenCurrent->next;
34        }
35      
36        // Connect the end of odd list to the beginning of even list
37        oddCurrent->next = evenHead;
38      
39        return head;
40    }
41};
421/**
2 * Definition for singly-linked list.
3 * class ListNode {
4 *     val: number
5 *     next: ListNode | null
6 *     constructor(val?: number, next?: ListNode | null) {
7 *         this.val = (val===undefined ? 0 : val)
8 *         this.next = (next===undefined ? null : next)
9 *     }
10 * }
11 */
12
13/**
14 * Rearranges a linked list so that all odd-positioned nodes come first,
15 * followed by all even-positioned nodes.
16 * The relative order within odd and even groups is preserved.
17 * 
18 * @param head - The head of the linked list
19 * @returns The head of the rearranged linked list
20 */
21function oddEvenList(head: ListNode | null): ListNode | null {
22    // Handle empty list
23    if (!head) {
24        return null;
25    }
26  
27    // Initialize pointers:
28    // oddTail: tracks the last node in the odd-positioned group
29    // evenTail: tracks the last node in the even-positioned group  
30    // evenHead: stores the head of the even-positioned group for later connection
31    let oddTail: ListNode = head;
32    let evenTail: ListNode | null = head.next;
33    let evenHead: ListNode | null = head.next;
34  
35    // Traverse the list and separate odd and even positioned nodes
36    while (evenTail && evenTail.next) {
37        // Connect current odd tail to the next odd-positioned node
38        oddTail.next = evenTail.next;
39        oddTail = oddTail.next;
40      
41        // Connect current even tail to the next even-positioned node
42        evenTail.next = oddTail.next;
43        evenTail = evenTail.next;
44    }
45  
46    // Connect the end of odd-positioned nodes to the head of even-positioned nodes
47    oddTail.next = evenHead;
48  
49    return head;
50}
51Time and Space Complexity
Time Complexity: O(n), where n is the number of nodes in the linked list. The algorithm traverses the entire linked list exactly once using the while loop. Each node is visited and processed with constant time operations (pointer reassignments), resulting in linear time complexity.
Space Complexity: O(1). The algorithm uses only a constant amount of extra space regardless of the input size. It maintains three pointers (a, b, and c) to rearrange the nodes in-place. No additional data structures are created that scale with the input size, making the space complexity constant.
Common Pitfalls
Pitfall 1: Not Preserving the Even List Head
One of the most common mistakes is forgetting to save a reference to the head of the even list before starting the rewiring process. If you don't store even_head = head.next at the beginning, you'll lose access to the even nodes after reorganizing the pointers.
Incorrect approach:
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
    if head is None:
        return None
  
    odd_current = head
    even_current = head.next
    # Missing: even_head = head.next
  
    while even_current and even_current.next:
        odd_current.next = even_current.next
        odd_current = odd_current.next
        even_current.next = odd_current.next
        even_current = even_current.next
  
    # This will fail - we don't have reference to even list's head!
    odd_current.next = ???  # Lost reference to even nodes
  
    return head
Solution: Always save the head of the even list before modifying any pointers.
Pitfall 2: Incorrect Loop Condition
Another frequent error is using the wrong loop condition, which can lead to null pointer exceptions or incomplete processing.
Incorrect approaches:
# Wrong: Only checking even_current
while even_current:  # This can cause NullPointerException
    odd_current.next = even_current.next  # even_current.next might not exist
  
# Wrong: Only checking even_current.next
while even_current.next:  # Misses the case when even_current itself is None
Solution: Use while even_current and even_current.next: to ensure both the current even node and the next node exist before attempting to access even_current.next.
Pitfall 3: Forgetting Edge Cases
Failing to handle edge cases properly, particularly:
- Empty list (head is None)
 - Single node list
 - Two node list
 
Incorrect approach:
def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
    # Missing null check - will crash on empty list
    odd_current = head
    even_head = head.next  # NullPointerException if head is None
    even_current = head.next
Solution: Always check if head is None before accessing head.next. The algorithm naturally handles single and two-node lists correctly with the proper loop condition.
Pitfall 4: Incorrect Pointer Movement Order
Moving pointers in the wrong order or forgetting to move them can create infinite loops or incorrect connections.
Incorrect approach:
while even_current and even_current.next:
    # Forgetting to move odd_current forward
    odd_current.next = even_current.next
    # Missing: odd_current = odd_current.next
  
    even_current.next = odd_current.next  # This uses wrong odd_current position
    even_current = even_current.next
Solution: Always update pointers immediately after modifying their next references to maintain correct positions for the next iteration.
Which type of traversal does breadth first search do?
Recommended Readings
Linked List Cycle Given a linked list with potentially a loop determine whether the linked list from the first node contains a cycle in it For bonus points do this with constant space Parameters nodes The first node of a linked list with potentially a loop Result Whether there is a loop contained
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion If you prefer videos here's a video that explains recursion in a fun and easy way Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask him
Want a Structured Path to Master System Design Too? Don’t Miss This!