🧠
Recursive Approach (Not Recommended for Large Inputs)
💡 This approach uses recursion to separate odd and even nodes by index, but it is less efficient and risks stack overflow for large lists. It is useful to understand recursion on linked lists.
Intuition
Recursively process the list, linking odd nodes first, then even nodes, by passing the current index and rearranging pointers accordingly.
Algorithm
- Define a recursive helper that takes current node and index.
- If node is null, return null.
- If index is odd, link current node to recursive call on next node with index+1.
- If index is even, link current node to recursive call on next node with index+1.
- After recursion, connect the last odd node to the head of even nodes.
- Return the head of the odd nodes.
💡 Managing two separate recursive chains and connecting them at the end is tricky and error-prone.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def oddEvenList(head):
def helper(node, index):
if not node:
return (None, None) # (odd_head, even_head)
odd_head, even_head = helper(node.next, index + 1)
if index % 2 == 1:
node.next = odd_head
return (node, even_head)
else:
node.next = even_head
return (odd_head, node)
odd_head, even_head = helper(head, 1)
# Find tail of odd list
curr = odd_head
while curr and curr.next:
curr = curr.next
if curr:
curr.next = even_head
return odd_head
# Driver code
if __name__ == '__main__':
head = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
new_head = oddEvenList(head)
curr = new_head
res = []
while curr:
res.append(curr.val)
curr = curr.next
print(res) # Expected: [1,3,5,2,4]
Line Notes
def helper(node, index):Recursive helper to process nodes with index tracking.
if not node:Base case: end of list returns empty odd and even heads.
odd_head, even_head = helper(node.next, index + 1)Recursive call to process next node.
if index % 2 == 1:If current node is odd positioned, link to odd list.
node.next = odd_headLink current odd node to previously processed odd nodes.
return (node, even_head)Return updated odd head and even head.
while curr and curr.next:Traverse odd list to find tail for connection.
curr.next = even_headConnect odd list tail to even list head.
class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
}
public class Solution {
private ListNode oddHead = null;
private ListNode evenHead = null;
private ListNode[] helper(ListNode node, int index) {
if (node == null) return new ListNode[]{null, null};
ListNode[] heads = helper(node.next, index + 1);
if (index % 2 == 1) {
node.next = heads[0];
return new ListNode[]{node, heads[1]};
} else {
node.next = heads[1];
return new ListNode[]{heads[0], node};
}
}
public ListNode oddEvenList(ListNode head) {
ListNode[] heads = helper(head, 1);
ListNode odd = heads[0];
ListNode even = heads[1];
ListNode curr = odd;
while (curr != null && curr.next != null) {
curr = curr.next;
}
if (curr != null) {
curr.next = even;
}
return odd;
}
public static void main(String[] args) {
Solution sol = new Solution();
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
head.next.next.next.next = new ListNode(5);
ListNode newHead = sol.oddEvenList(head);
ListNode curr = newHead;
while (curr != null) {
System.out.print(curr.val + " ");
curr = curr.next;
}
// Expected output: 1 3 5 2 4
}
}
Line Notes
private ListNode[] helper(ListNode node, int index)Recursive helper returns odd and even heads as array.
if (node == null) return new ListNode[]{null, null};Base case returns empty lists.
ListNode[] heads = helper(node.next, index + 1);Recursive call to next node.
if (index % 2 == 1)If current node is odd positioned, link to odd list.
node.next = heads[0];Link current odd node to odd list head.
return new ListNode[]{node, heads[1]};Return updated odd and even heads.
while (curr != null && curr.next != null)Find tail of odd list to connect even list.
curr.next = even;Connect odd list tail to even list head.
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
pair<ListNode*, ListNode*> helper(ListNode* node, int index) {
if (!node) return {nullptr, nullptr};
auto heads = helper(node->next, index + 1);
if (index % 2 == 1) {
node->next = heads.first;
return {node, heads.second};
} else {
node->next = heads.second;
return {heads.first, node};
}
}
ListNode* oddEvenList(ListNode* head) {
auto heads = helper(head, 1);
ListNode* odd = heads.first;
ListNode* even = heads.second;
ListNode* curr = odd;
while (curr && curr->next) {
curr = curr->next;
}
if (curr) {
curr->next = even;
}
return odd;
}
};
int main() {
Solution sol;
ListNode* head = new ListNode(1);
head->next = new ListNode(2);
head->next->next = new ListNode(3);
head->next->next->next = new ListNode(4);
head->next->next->next->next = new ListNode(5);
ListNode* newHead = sol.oddEvenList(head);
ListNode* curr = newHead;
while (curr) {
cout << curr->val << " ";
curr = curr->next;
}
// Expected output: 1 3 5 2 4
return 0;
}
Line Notes
pair<ListNode*, ListNode*> helper(ListNode* node, int index)Recursive helper returns pair of odd and even heads.
if (!node) return {nullptr, nullptr};Base case returns empty lists.
auto heads = helper(node->next, index + 1);Recursive call to next node.
if (index % 2 == 1)If current node is odd positioned, link to odd list.
node->next = heads.first;Link current odd node to odd list head.
return {node, heads.second};Return updated odd and even heads.
while (curr && curr->next)Find tail of odd list to connect even list.
curr->next = even;Connect odd list tail to even list head.
function ListNode(val, next = null) {
this.val = val;
this.next = next;
}
function oddEvenList(head) {
function helper(node, index) {
if (!node) return [null, null];
const [oddHead, evenHead] = helper(node.next, index + 1);
if (index % 2 === 1) {
node.next = oddHead;
return [node, evenHead];
} else {
node.next = evenHead;
return [oddHead, node];
}
}
const [oddHead, evenHead] = helper(head, 1);
let curr = oddHead;
while (curr && curr.next) {
curr = curr.next;
}
if (curr) {
curr.next = evenHead;
}
return oddHead;
}
// Test
const head = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5)))));
const newHead = oddEvenList(head);
let curr = newHead;
const res = [];
while (curr) {
res.push(curr.val);
curr = curr.next;
}
console.log(res); // Expected: [1,3,5,2,4]
Line Notes
function helper(node, index)Recursive helper returns odd and even heads as array.
if (!node) return [null, null];Base case returns empty lists.
const [oddHead, evenHead] = helper(node.next, index + 1);Recursive call to next node.
if (index % 2 === 1)If current node is odd positioned, link to odd list.
node.next = oddHead;Link current odd node to odd list head.
return [node, evenHead];Return updated odd and even heads.
while (curr && curr.next)Find tail of odd list to connect even list.
curr.next = evenHead;Connect odd list tail to even list head.
Each node is visited once, but recursion uses stack space proportional to n.
💡 For n=1000, this means 1000 recursive calls which risks stack overflow in some languages.
Interview Verdict: Accepted but not recommended due to recursion overhead
Good for understanding recursion but not practical for large inputs or interviews focused on efficiency.