Odd Even Linked List medium
Problem Statement
Given the head
of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return the reordered list.
The first node is considered odd, the second node is even, and so on.
Note:
- The relative order inside both the even and odd groups should remain as it was in the input.
- You must solve the problem in
O(1)
extra space complexity andO(n)
time complexity.
Example 1
Input: head = [1,2,3,4,5] Output: [1,3,5,2,4]
Example 2
Input: head = [2,1,3,5,6,4,7] Output: [2,3,6,7,1,5,4]
Steps
-
Handle edge cases: If the list is empty or has only one node, return the head.
-
Initialize pointers: Create pointers
odd
andeven
to track the heads of the odd and even sublists, respectively. Also, create pointersodd_tail
andeven_tail
to track the tails of the odd and even sublists for efficient appending. -
Iterate through the list: Iterate through the linked list, using a
current
pointer. -
Separate odd and even nodes: For each node:
- If the node's index is odd, append it to the
odd
sublist usingodd_tail
. - If the node's index is even, append it to the
even
sublist usingeven_tail
.
- If the node's index is odd, append it to the
-
Connect odd and even sublists: After iterating, connect the tail of the
odd
sublist to the head of theeven
sublist.
Explanation
The algorithm maintains two separate lists – one for odd-indexed nodes and one for even-indexed nodes. It iterates through the original list, assigning each node to its respective list. Finally, it links the tail of the odd list to the head of the even list to produce the reordered list. This approach ensures that the relative order within each group (odd and even) is preserved. The use of tail pointers avoids the need to traverse the lists repeatedly for appending nodes, contributing to the O(n) time complexity.
Code
/**
* 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* oddEvenList(ListNode* head) {
if (!head || !head->next) return head; // Handle edge cases
ListNode* odd = head; // Head of odd sublist
ListNode* even = head->next; // Head of even sublist
ListNode* odd_tail = odd; // Tail of odd sublist
ListNode* even_tail = even; // Tail of even sublist
ListNode* current = even->next; // Current node for iteration
bool odd_turn = false; //true for odd false for even. starts with even
while (current) {
if(odd_turn){
odd_tail->next = current;
odd_tail = odd_tail->next;
} else {
even_tail->next = current;
even_tail = even_tail->next;
}
current = current->next;
odd_turn = !odd_turn;
}
odd_tail->next = even;
even_tail->next = nullptr;
return odd;
}
};
Complexity
- Time Complexity: O(n), where n is the number of nodes in the linked list. We iterate through the list once.
- Space Complexity: O(1). We use only a constant number of pointers.