Bird
Raised Fist0
DSA Goprogramming

Merge Two Sorted Linked Lists in DSA Go

Choose your learning style10 modes available
Mental Model
We combine two sorted lists by always picking the smaller front item from either list and linking it to the new list.
Analogy: Imagine merging two lines of people sorted by height into one line, always letting the shorter person step forward first.
List1: 1 -> 3 -> 5 -> null
List2: 2 -> 4 -> 6 -> null
Merged: null
Dry Run Walkthrough
Input: list1: 1->3->5, list2: 2->4->6
Goal: Create one sorted list containing all elements from both lists
Step 1: Compare heads: 1 (list1) vs 2 (list2), pick 1
Merged: 1 -> null
List1: 3 -> 5 -> null
List2: 2 -> 4 -> 6 -> null
Why: We pick the smaller element to keep merged list sorted
Step 2: Compare heads: 3 (list1) vs 2 (list2), pick 2
Merged: 1 -> 2 -> null
List1: 3 -> 5 -> null
List2: 4 -> 6 -> null
Why: Next smallest is 2 from list2
Step 3: Compare heads: 3 (list1) vs 4 (list2), pick 3
Merged: 1 -> 2 -> 3 -> null
List1: 5 -> null
List2: 4 -> 6 -> null
Why: 3 is smaller, so add it next
Step 4: Compare heads: 5 (list1) vs 4 (list2), pick 4
Merged: 1 -> 2 -> 3 -> 4 -> null
List1: 5 -> null
List2: 6 -> null
Why: 4 is smaller, add it next
Step 5: Compare heads: 5 (list1) vs 6 (list2), pick 5
Merged: 1 -> 2 -> 3 -> 4 -> 5 -> null
List1: null
List2: 6 -> null
Why: 5 is smaller, add it next
Step 6: List1 empty, append remaining list2 nodes
Merged: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null
List1: null
List2: null
Why: No more nodes in list1, add rest of list2
Result:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null
Annotated Code
DSA Go
package main

import "fmt"

type ListNode struct {
	Val  int
	Next *ListNode
}

func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
	dummy := &ListNode{} // dummy node to start merged list
	current := dummy

	for list1 != nil && list2 != nil {
		if list1.Val < list2.Val {
			current.Next = list1 // link smaller node
			list1 = list1.Next // move list1 forward
		} else {
			current.Next = list2 // link smaller or equal node
			list2 = list2.Next // move list2 forward
		}
		current = current.Next // move current forward
	}

	if list1 != nil {
		current.Next = list1 // append remaining list1 nodes
	} else {
		current.Next = list2 // append remaining list2 nodes
	}

	return dummy.Next // return merged list head
}

func printList(head *ListNode) {
	for head != nil {
		fmt.Printf("%d", head.Val)
		if head.Next != nil {
			fmt.Printf(" -> ")
		}
		head = head.Next
	}
	fmt.Println(" -> null")
}

func main() {
	// Create list1: 1 -> 3 -> 5 -> null
	list1 := &ListNode{Val: 1}
	list1.Next = &ListNode{Val: 3}
	list1.Next.Next = &ListNode{Val: 5}

	// Create list2: 2 -> 4 -> 6 -> null
	list2 := &ListNode{Val: 2}
	list2.Next = &ListNode{Val: 4}
	list2.Next.Next = &ListNode{Val: 6}

	merged := mergeTwoLists(list1, list2)
	printList(merged)
}
for list1 != nil && list2 != nil {
loop until one list is empty
if list1.Val < list2.Val {
compare current nodes to pick smaller
current.Next = list1
link smaller node from list1
list1 = list1.Next
advance list1 pointer
current.Next = list2
link smaller or equal node from list2
list2 = list2.Next
advance list2 pointer
current = current.Next
advance current pointer in merged list
if list1 != nil { current.Next = list1 } else { current.Next = list2 }
append remaining nodes after one list ends
return dummy.Next
return head of merged list skipping dummy
OutputSuccess
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null
Complexity Analysis
Time: O(n + m) because we traverse each node from both lists once
Space: O(1) because we only rearrange pointers without extra storage
vs Alternative: Compared to merging into a new list with new nodes, this approach reuses existing nodes saving space and time
Edge Cases
One or both lists empty
Returns the non-empty list or nil if both empty
DSA Go
if list1 != nil { current.Next = list1 } else { current.Next = list2 }
Lists with duplicate values
Duplicates are merged preserving order
DSA Go
if list1.Val < list2.Val { ... } else { ... }
Lists of different lengths
Remaining nodes of longer list appended after shorter ends
DSA Go
if list1 != nil { current.Next = list1 } else { current.Next = list2 }
When to Use This Pattern
When you see two sorted lists and need one sorted list, reach for merge pattern because it efficiently combines them by comparing front elements.
Common Mistakes
Mistake: Not advancing the current pointer after linking a node
Fix: Always move current = current.Next after linking to keep building merged list
Mistake: Forgetting to append remaining nodes after one list ends
Fix: Add code to link remaining nodes after loop ends
Summary
It merges two sorted linked lists into one sorted linked list by picking smaller nodes step-by-step.
Use it when you have two sorted lists and want to combine them without sorting again.
The key insight is to always pick the smaller front node from either list to keep the merged list sorted.

Practice

(1/5)
1. What is the main goal when merging two sorted linked lists?
easy
A. Remove duplicates from both lists without merging
B. Sort each list separately without combining them
C. Create a new sorted linked list containing all elements from both lists
D. Reverse both lists and then merge

Solution

  1. Step 1: Understand the merge operation

    Merging means combining two lists into one while keeping the order sorted.
  2. Step 2: Identify the goal of merging sorted lists

    The goal is to create a new sorted list that contains all elements from both input lists.
  3. Final Answer:

    Create a new sorted linked list containing all elements from both lists -> Option C
  4. Quick Check:

    Merge = Combine sorted lists [OK]
Hint: Merging means combining sorted lists into one sorted list [OK]
Common Mistakes:
  • Thinking merge means sorting each list separately
  • Confusing merge with removing duplicates only
  • Assuming merge reverses the lists
2. Which of the following is the correct Go syntax to define a node struct for a singly linked list?
easy
A. Node := struct { val int; next Node }
B. struct Node { int val; Node* next; }
C. class Node { int val; Node next; }
D. type Node struct { val int; next *Node }

Solution

  1. Step 1: Recall Go struct syntax

    In Go, structs are defined with 'type Name struct { fields }' and pointers use '*'.
  2. Step 2: Check each option

    type Node struct { val int; next *Node } uses correct Go syntax with pointer '*Node' for next node.
  3. Final Answer:

    type Node struct { val int; next *Node } -> Option D
  4. Quick Check:

    Go struct with pointer = type Node struct { val int; next *Node } [OK]
Hint: Go structs use 'type' and pointers with '*' [OK]
Common Mistakes:
  • Using C/C++ or Java syntax in Go
  • Missing pointer '*' for next node
  • Using := inside struct definition
3. What is the output linked list after merging these two sorted lists?

List1: 1 -> 3 -> 5 -> null
List2: 2 -> 4 -> 6 -> null

Assume the merge function returns the head of the merged list.
medium
A. 2 -> 4 -> 6 -> 1 -> 3 -> 5 -> null
B. 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null
C. 1 -> 3 -> 5 -> 2 -> 4 -> 6 -> null
D. 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> null

Solution

  1. Step 1: Compare first nodes of both lists

    1 (List1) < 2 (List2), so start merged list with 1.
  2. Step 2: Continue comparing next nodes in order

    Next compare 3 and 2, 2 is smaller, add 2; then 3 and 4, add 3; then 5 and 4, add 4; then 5 and 6, add 5; finally add 6.
  3. Final Answer:

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

    Merge sorted lists = sorted combined list [OK]
Hint: Pick smaller node each step to merge sorted lists [OK]
Common Mistakes:
  • Appending one list after the other without sorting
  • Reversing the order accidentally
  • Skipping nodes during merge
4. Given this Go function snippet to merge two sorted linked lists, what is the bug?

func mergeLists(l1, l2 *Node) *Node {
    if l1 == nil {
        return l2
    }
    if l2 == nil {
        return l1
    }
    if l1.val < l2.val {
        l1.next = mergeLists(l1.next, l2)
        return l1
    } else {
        l2.next = mergeLists(l1, l2.next)
        return l2
    }
}
medium
A. No bug, function correctly merges two sorted lists
B. Missing base case for both lists being nil
C. Incorrect comparison operator, should be <= instead of <
D. Function does not handle cycles in lists

Solution

  1. Step 1: Analyze base cases

    Function returns the other list if one is nil, which is correct.
  2. Step 2: Check recursive merge logic

    Function compares values and recursively merges the rest correctly.
  3. Final Answer:

    No bug, function correctly merges two sorted lists -> Option A
  4. Quick Check:

    Recursive merge with base cases = correct [OK]
Hint: Check base cases and recursion for correctness [OK]
Common Mistakes:
  • Thinking missing base case for both nil (not needed)
  • Confusing < with <= (both work here)
  • Ignoring cycle detection (not required here)
5. You have two sorted linked lists:
List1: 1 -> 4 -> 7 -> 10 -> null
List2: 2 -> 3 -> 5 -> 8 -> 12 -> null

Write a Go function to merge these lists iteratively and return the merged list head. What will be the final merged list?
hard
A. 1 -> 2 -> 3 -> 4 -> 5 -> 7 -> 8 -> 10 -> 12 -> null
B. 1 -> 4 -> 7 -> 10 -> 2 -> 3 -> 5 -> 8 -> 12 -> null
C. 2 -> 3 -> 5 -> 8 -> 12 -> 1 -> 4 -> 7 -> 10 -> null
D. 12 -> 10 -> 8 -> 7 -> 5 -> 4 -> 3 -> 2 -> 1 -> null

Solution

  1. Step 1: Initialize dummy node and pointer

    Create a dummy node to start merged list and a pointer to track current node.
  2. Step 2: Iterate and compare nodes from both lists

    Compare current nodes from List1 and List2, attach smaller to merged list, move pointer forward.
  3. Step 3: Attach remaining nodes after one list ends

    Once one list is exhausted, attach the rest of the other list.
  4. Final Answer:

    1 -> 2 -> 3 -> 4 -> 5 -> 7 -> 8 -> 10 -> 12 -> null -> Option A
  5. Quick Check:

    Iterative merge keeps sorted order [OK]
Hint: Use dummy node and iterate picking smaller nodes [OK]
Common Mistakes:
  • Appending lists without sorting
  • Forgetting to attach remaining nodes
  • Not using a dummy node causing complex code
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