Bird
Raised Fist0
Interview Preplinked-list-advancedmediumAmazonGoogleFacebook

Odd Even Linked List

Choose your preparation mode4 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Steps
setup

Initialize / Setup

The linked list is created with nodes 1 → 2 → 3 → 4 → 5. The head pointer references node 1.

💡 Setting up the initial list is essential to visualize how nodes will be rearranged.
Line:head = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
💡 The initial structure and head pointer are established for the recursive process.
📊
Odd Even Linked List - Watch the Algorithm Execute, Step by Step
Watching each recursive call and pointer reassignment reveals how the list is split and merged without extra space.
Step 1/20
·Active fillAnswer cell
advance
1
2
3
4
5
traverse
1
2
3
4
5
traverse
1
2
3
4
5
traverse
1
2
3
4
5
traverse
1
2
3
4
5
traverse
1
2
3
4
5
traverse
1
2
3
4
5
connect
5
Result:
Odd head:5
Even head:null
connect
5
4
Result:
Odd head:5
Even head:4
connect
3
5
4
Result:
Odd head:3
Even head:4
connect
3
5
2
4
Result:
Odd head:3
Even head:2
connect
1
3
5
2
4
Result:
Odd head:1
Even head:2
traverse
1
3
5
2
4
Result:
Odd head:1
Even head:2
connect
1
3
5
2
4
advance
1
3
5
2
4
traverse
1
3
5
2
4
Result: [1]
traverse
1
3
5
2
4
Result: [1, 3]
traverse
1
3
5
2
4
Result: [1, 3, 5]
traverse
1
3
5
2
4
Result: [1, 3, 5, 2]
traverse
1
3
5
2
4
Result: [1, 3, 5, 2, 4]

Key Takeaways

The recursive approach separates odd and even nodes by index during the call stack unwind, building two lists simultaneously.

This insight is hard to see from code alone because recursion hides the order of operations until return.

Odd nodes are linked to the previously returned odd list head, and even nodes to the even list head, effectively reversing the list during recursion.

Visualizing pointer reassignments clarifies how the list is rebuilt in correct order.

The final step connects the tail of the odd list to the head of the even list, merging the two sublists into the final reordered list.

Understanding this merge is key to grasping how the algorithm produces the final output.

Practice

(1/5)
1. Given the following code snippet for splitting a linked list into k=3 parts, and the input list 1->2->3->4, what is the returned list of parts (values only)?
easy
A. [[1, 2], [3, 4], []]
B. [[1, 2], [3], [4]]
C. [[1, 2], [3], [4, None]]
D. [[1], [2], [3, 4]]

Solution

  1. Step 1: Calculate total nodes and part sizes

    Total nodes = 4, k = 3, so part_size = 1, remainder = 1. First remainder parts get one extra node.
  2. Step 2: Assign nodes to parts

    Part 0 size = 2 nodes (1,2), Part 1 size = 1 node (3), Part 2 size = 1 node (4). The returned parts are [[1,2],[3],[4]].
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Sum of parts equals original list length and sizes differ by at most one [OK]
Hint: Remainder nodes assigned to first parts -> first part larger [OK]
Common Mistakes:
  • Assigning remainder nodes to last parts
  • Off-by-one in part sizes
  • Returning fewer than k parts
2. What is the time complexity of the recursive approach that converts a binary number in a linked list to an integer by accumulating the value with bit shifts?
medium
A. O(n log n) due to bit shifts at each node
B. O(n^2) because recursion stack causes repeated computations
C. O(n) because each node is visited once with constant work
D. O(n) time but O(n^2) space due to recursion stack

Solution

  1. Step 1: Analyze time per node

    Each node is processed once, performing a constant number of bit operations (shift and OR).
  2. Step 2: Consider recursion overhead

    Recursion depth is n, but no repeated computations occur; each call does O(1) work.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Linear traversal with constant work per node [OK]
Hint: Bit shifts are O(1) operations, not O(log n) [OK]
Common Mistakes:
  • Assuming bit shifts cost O(log n)
  • Confusing recursion stack space with time complexity
  • Thinking recursion causes repeated work
3. The following code attempts to implement the two stacks browser history. Identify the line containing the subtle bug that causes forward navigation to return outdated pages after visiting a new URL.
class BrowserHistory:
    def __init__(self, homepage: str):
        self.back_stack = [homepage]
        self.forward_stack = []

    def visit(self, url: str) -> None:
        self.back_stack.append(url)
        # Missing forward_stack.clear() here

    def back(self, steps: int) -> str:
        while steps > 0 and len(self.back_stack) > 1:
            self.forward_stack.append(self.back_stack.pop())
            steps -= 1
        return self.back_stack[-1]

    def forward(self, steps: int) -> str:
        while steps > 0 and self.forward_stack:
            self.back_stack.append(self.forward_stack.pop())
            steps -= 1
        return self.back_stack[-1]
medium
A. Line where back_stack.append(url) is called in visit
B. Line where forward_stack.clear() should be called but is missing in visit
C. Line where back_stack.pop() is called in back method
D. Line where forward_stack.pop() is called in forward method

Solution

  1. Step 1: Identify visit method behavior

    Visit appends new URL but does not clear forward_stack, so forward history remains outdated.
  2. Step 2: Understand impact on forward navigation

    Without clearing forward_stack, forward() returns stale pages that should have been discarded.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Clearing forward_stack on visit is essential to maintain correct forward history [OK]
Hint: Visit must clear forward history to avoid stale pages [OK]
Common Mistakes:
  • Forgetting to clear forward stack on visit
  • Incorrectly popping from back stack
  • Mismanaging stack boundaries
4. Consider the following buggy code snippet for reversing nodes in k-groups. Which line contains the subtle bug that can cause incorrect output when the list length is not a multiple of k?
medium
A. Line missing the check 'if count < k: break' after counting nodes
B. Line with 'group_next = kth.next' assignment
C. Line with 'while kth.next and count < k:' loop
D. Line with 'tmp.next = group_next' pointer update

Solution

  1. Step 1: Identify missing boundary check

    The code does not check if the remaining nodes are fewer than k before reversal.
  2. Step 2: Consequence of missing check

    Without 'if count < k: break', partial groups get reversed incorrectly, breaking problem constraints.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Missing break causes partial group reversal [OK]
Hint: Always check group size before reversal [OK]
Common Mistakes:
  • Forgetting to break on partial group
  • Misplacing pointer updates
  • Assuming kth always valid
5. Suppose the problem is modified so that nodes can be reused multiple times (i.e., after reversing a group, nodes can appear again in subsequent groups). Which of the following changes to the algorithm correctly handles this scenario?
hard
A. Modify the algorithm to create new nodes for each group reversal to avoid modifying original nodes in place.
B. This problem cannot be solved by reversal; instead, use a queue to simulate repeated node usage.
C. Use recursion with memoization to store reversed groups and reuse them without modifying the original list.
D. Use the same iterative reversal approach but reset pointers to allow reusing nodes in multiple groups.

Solution

  1. Step 1: Understand node reuse implication

    Reusing nodes means original nodes must remain unchanged or duplicated to appear multiple times.
  2. Step 2: Evaluate algorithm modifications

    In-place reversal modifies nodes destructively, so creating new nodes for each group is necessary to preserve original nodes.
  3. Step 3: Assess other options

    Resetting pointers (A) breaks list integrity; recursion with memoization (C) is complex and not standard; queue simulation (B) does not solve reversal reuse.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Duplicating nodes preserves original list for reuse [OK]
Hint: Node reuse requires duplication, not in-place reversal [OK]
Common Mistakes:
  • Trying to reuse nodes in place
  • Ignoring list integrity
  • Assuming recursion memoization solves reuse