Bird
Raised Fist0
DSA Goprogramming

Reorder Linked List in DSA Go

Choose your learning style10 modes available
Mental Model
We rearrange a linked list so nodes alternate from start and end, meeting in the middle.
Analogy: Imagine lining up people from two ends of a line to form a new line by picking one from front, then one from back, and so on.
1 -> 2 -> 3 -> 4 -> 5 -> null
↑
Dry Run Walkthrough
Input: list: 1 -> 2 -> 3 -> 4 -> 5 -> null
Goal: Rearrange list to 1 -> 5 -> 2 -> 4 -> 3 -> null
Step 1: Find middle node using slow and fast pointers
1 -> 2 -> 3 -> 4 -> 5 -> null
          ↑slow, ↑fast
Why: We need to split the list into two halves at the middle
Step 2: Split list into two halves at middle
First half: 1 -> 2 -> 3 -> null
Second half: 4 -> 5 -> null
Why: Separating halves allows reversing second half independently
Step 3: Reverse second half
Second half reversed: 5 -> 4 -> null
Why: Reversing second half prepares it for alternating merge
Step 4: Merge nodes alternately from first and reversed second half
1 -> 5 -> 2 -> 4 -> 3 -> null
Why: Alternating nodes from front and back achieves the reorder
Result:
1 -> 5 -> 2 -> 4 -> 3 -> null
Annotated Code
DSA Go
package main

import "fmt"

type ListNode struct {
	Val  int
	Next *ListNode
}

func reorderList(head *ListNode) {
	if head == nil || head.Next == nil {
		return
	}

	// Find middle using slow and fast pointers
	slow, fast := head, head
	for fast != nil && fast.Next != nil {
		slow = slow.Next
		fast = fast.Next.Next
	}

	// Split and reverse second half
	second := slow.Next
	slow.Next = nil
	second = reverseList(second)

	// Merge two halves alternately
	first := head
	for second != nil {
		// Save next pointers
		t1 := first.Next
		t2 := second.Next

		// Link first to second
		first.Next = second

		// Link second to t1
		second.Next = t1

		// Move pointers forward
		first = t1
		second = t2
	}
}

func reverseList(head *ListNode) *ListNode {
	var prev *ListNode
	curr := head
	for curr != nil {
		nextTemp := curr.Next
		curr.Next = prev
		prev = curr
		curr = nextTemp
	}
	return prev
}

func printList(head *ListNode) {
	curr := head
	for curr != nil {
		fmt.Print(curr.Val)
		if curr.Next != nil {
			fmt.Print(" -> ")
		}
		curr = curr.Next
	}
	fmt.Println(" -> null")
}

func main() {
	head := &ListNode{1, &ListNode{2, &ListNode{3, &ListNode{4, &ListNode{5, nil}}}}}
	fmt.Print("Original list: ")
	printList(head)

	reorderList(head)

	fmt.Print("Reordered list: ")
	printList(head)
}
slow, fast := head, head
Initialize pointers to find middle node
for fast != nil && fast.Next != nil { slow = slow.Next fast = fast.Next.Next }
Advance slow by one and fast by two to find middle
second := slow.Next slow.Next = nil
Split list into two halves at middle
second = reverseList(second)
Reverse second half for merging
for second != nil { t1 := first.Next t2 := second.Next first.Next = second second.Next = t1 first = t1 second = t2 }
Merge nodes alternately from first and reversed second half
OutputSuccess
Original list: 1 -> 2 -> 3 -> 4 -> 5 -> null Reordered list: 1 -> 5 -> 2 -> 4 -> 3 -> null
Complexity Analysis
Time: O(n) because we traverse the list multiple times but each node is visited a constant number of times
Space: O(1) because we reorder the list in place without extra data structures
vs Alternative: Compared to creating a new list or array to reorder, this approach uses constant space and is more efficient
Edge Cases
Empty list
Function returns immediately without changes
DSA Go
if head == nil || head.Next == nil { return }
Single node list
Function returns immediately without changes
DSA Go
if head == nil || head.Next == nil { return }
List with two nodes
List remains the same as reorder does not change order
DSA Go
for fast != nil && fast.Next != nil { ... } handles this gracefully
When to Use This Pattern
When asked to reorder a linked list alternating from front and back, use the reorder list pattern by splitting, reversing second half, and merging.
Common Mistakes
Mistake: Not splitting the list properly causing cycles or incorrect merges
Fix: Set slow.Next = nil to break the list into two halves before reversing
Mistake: Forgetting to reverse the second half before merging
Fix: Reverse the second half to ensure correct alternating order
Mistake: Incorrect pointer updates during merge causing lost nodes
Fix: Save next pointers before re-linking and update pointers carefully
Summary
Rearranges a linked list so nodes alternate from front and back.
Use when you need to reorder nodes in a specific alternating pattern without extra space.
Split the list, reverse the second half, then merge nodes alternately.

Practice

(1/5)
1. What is the main goal of the Reorder Linked List problem?
easy
A. Rearrange the list so nodes alternate from start and end towards the center
B. Sort the linked list in ascending order
C. Reverse the entire linked list
D. Remove duplicate nodes from the linked list

Solution

  1. Step 1: Understand the problem statement

    The problem asks to reorder the list so that nodes come alternately from the start and the end, like L0 -> Ln -> L1 -> Ln-1 -> L2 -> Ln-2 and so on.
  2. Step 2: Differentiate from other operations

    This is not sorting or reversing the entire list, but a specific pattern of rearrangement.
  3. Final Answer:

    Rearrange the list so nodes alternate from start and end towards the center -> Option A
  4. Quick Check:

    Reorder = alternate start/end nodes [OK]
Hint: Think of weaving nodes from front and back alternately [OK]
Common Mistakes:
  • Confusing reorder with sorting
  • Trying to reverse the whole list only
  • Ignoring the alternating pattern
2. Which of the following Go code snippets correctly declares a singly linked list node struct for the reorder linked list problem?
easy
A. class ListNode { int val; ListNode next; }
B. type ListNode struct { Val int; Next *ListNode }
C. struct ListNode { int Val; ListNode* Next; }
D. type ListNode struct { Value int; NextNode *ListNode }

Solution

  1. Step 1: Identify Go struct syntax

    In Go, structs are declared with the keyword type, fields have names and types separated by spaces, and pointers use *.
  2. Step 2: Match correct field names and types

    type ListNode struct { Val int; Next *ListNode } uses Val int and Next *ListNode, which is the standard for singly linked list nodes in Go.
  3. Final Answer:

    type ListNode struct { Val int; Next *ListNode } -> Option B
  4. Quick Check:

    Go struct with pointer field = type ListNode struct { Val int; Next *ListNode } [OK]
Hint: Remember Go struct fields: name type; pointer uses * [OK]
Common Mistakes:
  • Using C/C++ or Java syntax in Go
  • Missing pointer * for next node
  • Incorrect field names or types
3. Given the linked list 1 -> 2 -> 3 -> 4 -> 5 -> null, what is the reordered list after applying the reorder linked list algorithm?
medium
A. 1 -> 5 -> 2 -> 4 -> 3 -> null
B. 5 -> 4 -> 3 -> 2 -> 1 -> null
C. 1 -> 2 -> 3 -> 4 -> 5 -> null
D. 1 -> 3 -> 5 -> 2 -> 4 -> null

Solution

  1. Step 1: Identify the reorder pattern

    The reorder pattern takes the first node, then the last node, then second node, then second last node, and so on.
  2. Step 2: Apply pattern to given list

    Start: 1, end: 5, then 2, then 4, then 3 in the middle. So the reordered list is 1 -> 5 -> 2 -> 4 -> 3 -> null.
  3. Final Answer:

    1 -> 5 -> 2 -> 4 -> 3 -> null -> Option A
  4. Quick Check:

    Alternate front and back nodes = 1 -> 5 -> 2 -> 4 -> 3 -> null [OK]
Hint: Pick nodes alternately from front and back [OK]
Common Mistakes:
  • Reversing the entire list instead
  • Keeping original order unchanged
  • Mixing node order incorrectly
4. Consider this Go function snippet for reordering a linked list:
func reorderList(head *ListNode) {
    if head == nil || head.Next == nil { return }
    slow, fast := head, head
    for fast != nil && fast.Next != nil {
        slow = slow.Next
        fast = fast.Next.Next
    }
    second := slow.Next
    slow.Next = nil
    var prev *ListNode
    for second != nil {
        next := second.Next
        second.Next = prev
        prev = second
        second = next
    }
    first, second = head, prev
    for second != nil {
        tmp1 := first.Next
        tmp2 := second.Next
        first.Next = second
        second.Next = tmp1
        first = tmp1
        second = tmp2
    }
}
What is the bug in this code?
medium
A. The function does not handle empty or single-node lists
B. The middle node is not correctly found; slow pointer should start at head.Next
C. The loop to reverse the second half does not update the prev pointer correctly
D. The reversed second half is not properly linked back to the first half

Solution

  1. Step 1: Analyze the reversal and merging steps

    The code correctly finds the middle, reverses the second half, and then merges nodes alternately.
  2. Step 2: Identify the bug in linking halves

    After merging, the last node of the reordered list may still point to old nodes if not handled carefully. The code misses ensuring the last node's Next is nil, causing potential cycle or dangling links.
  3. Final Answer:

    The reversed second half is not properly linked back to the first half -> Option D
  4. Quick Check:

    Linking halves correctly is key [OK]
Hint: Check if last node's Next is set to nil after merge [OK]
Common Mistakes:
  • Not breaking the list at middle properly
  • Forgetting to set slow.Next = nil
  • Incorrect pointer updates in merge loop
5. You have a linked list with nodes containing values 1 -> 2 -> 3 -> null. After reordering, what will be the list if you apply the reorder linked list algorithm twice in a row?
hard
A. 1 -> 3 -> 2 -> null (same as after first reorder)
B. 3 -> 2 -> 1 -> null
C. 1 -> 2 -> 3 -> null (original list)
D. 2 -> 3 -> 1 -> null

Solution

  1. Step 1: Apply reorder once

    First reorder transforms 1->2->3 into 1->3->2.
  2. Step 2: Apply reorder again on the new list

    Reordering 1->3->2 again returns the original order 1->2->3 because the reorder pattern is symmetric and reverses itself on second application.
  3. Final Answer:

    1 -> 2 -> 3 -> null (original list) -> Option C
  4. Quick Check:

    Reorder twice returns original list [OK]
Hint: Reordering twice restores original order [OK]
Common Mistakes:
  • Assuming reorder twice keeps the first reorder result
  • Not recognizing reorder symmetry
  • Confusing reorder with reverse
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard