Merge Two Sorted Linked Lists in DSA Go - Time & Space Complexity
When merging two sorted linked lists, we want to know how the time needed grows as the lists get longer.
We ask: How many steps does it take to combine both lists into one sorted list?
Analyze the time complexity of the following code snippet.
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
dummy := &ListNode{}
current := dummy
for l1 != nil && l2 != nil {
if l1.Val <= l2.Val {
current.Next = l1
l1 = l1.Next
} else {
current.Next = l2
l2 = l2.Next
}
current = current.Next
}
if l1 != nil {
current.Next = l1
} else {
current.Next = l2
}
return dummy.Next
}
This code merges two sorted linked lists by picking the smaller node from the heads repeatedly until one list ends, then appends the rest.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The
forloop that compares nodes from both lists. - How many times: Up to the total number of nodes in both lists combined (length of list1 + length of list2).
Each step processes one node from either list, so the total steps grow directly with the total nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 (5 + 5 nodes) | About 10 comparisons and moves |
| 100 (50 + 50 nodes) | About 100 comparisons and moves |
| 1000 (500 + 500 nodes) | About 1000 comparisons and moves |
Pattern observation: The number of steps grows linearly as the total number of nodes increases.
Time Complexity: O(n + m)
This means the time grows linearly with the total number of nodes in both lists combined.
[X] Wrong: "Merging two lists takes quadratic time because of nested loops."
[OK] Correct: The code only uses one loop that moves through both lists once, so it does not repeat work inside another loop.
Understanding this linear merging process helps you handle many linked list problems efficiently and shows you can work with pointers and lists clearly.
"What if the input lists were not sorted? How would the time complexity change if we still tried to merge them this way?"
Practice
Solution
Step 1: Understand the merge operation
Merging means combining two lists into one while keeping the order sorted.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.Final Answer:
Create a new sorted linked list containing all elements from both lists -> Option CQuick Check:
Merge = Combine sorted lists [OK]
- Thinking merge means sorting each list separately
- Confusing merge with removing duplicates only
- Assuming merge reverses the lists
Solution
Step 1: Recall Go struct syntax
In Go, structs are defined with 'type Name struct { fields }' and pointers use '*'.Step 2: Check each option
type Node struct { val int; next *Node } uses correct Go syntax with pointer '*Node' for next node.Final Answer:
type Node struct { val int; next *Node } -> Option DQuick Check:
Go struct with pointer = type Node struct { val int; next *Node } [OK]
- Using C/C++ or Java syntax in Go
- Missing pointer '*' for next node
- Using := inside struct definition
List1: 1 -> 3 -> 5 -> null
List2: 2 -> 4 -> 6 -> null
Assume the merge function returns the head of the merged list.
Solution
Step 1: Compare first nodes of both lists
1 (List1) < 2 (List2), so start merged list with 1.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.Final Answer:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null -> Option BQuick Check:
Merge sorted lists = sorted combined list [OK]
- Appending one list after the other without sorting
- Reversing the order accidentally
- Skipping nodes during merge
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
}
}Solution
Step 1: Analyze base cases
Function returns the other list if one is nil, which is correct.Step 2: Check recursive merge logic
Function compares values and recursively merges the rest correctly.Final Answer:
No bug, function correctly merges two sorted lists -> Option AQuick Check:
Recursive merge with base cases = correct [OK]
- Thinking missing base case for both nil (not needed)
- Confusing < with <= (both work here)
- Ignoring cycle detection (not required here)
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?
Solution
Step 1: Initialize dummy node and pointer
Create a dummy node to start merged list and a pointer to track current node.Step 2: Iterate and compare nodes from both lists
Compare current nodes from List1 and List2, attach smaller to merged list, move pointer forward.Step 3: Attach remaining nodes after one list ends
Once one list is exhausted, attach the rest of the other list.Final Answer:
1 -> 2 -> 3 -> 4 -> 5 -> 7 -> 8 -> 10 -> 12 -> null -> Option AQuick Check:
Iterative merge keeps sorted order [OK]
- Appending lists without sorting
- Forgetting to attach remaining nodes
- Not using a dummy node causing complex code
Ready to prove it?
Pass the test and this pattern moves unknown
