Merge Two Sorted Linked Lists in DSA C - Time & Space Complexity
We want to know how the time needed to merge two sorted linked lists changes as the lists get bigger.
Specifically, how does the number of steps grow when the input lists grow?
Analyze the time complexity of the following code snippet.
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
if (!l1) return l2;
if (!l2) return l1;
if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
This code merges two sorted linked lists by comparing their nodes and building a new sorted list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Comparing nodes from both lists and moving forward one node at a time.
- How many times: Each node from both lists is visited exactly once during the merge.
As the total number of nodes in both lists grows, the number of comparisons grows roughly the same amount.
| Input Size (n = total nodes) | Approx. Operations |
|---|---|
| 10 | About 10 comparisons |
| 100 | About 100 comparisons |
| 1000 | About 1000 comparisons |
Pattern observation: The number of steps grows linearly with the total number of nodes.
Time Complexity: O(n)
This means the time to merge grows directly in proportion to the total number of nodes in both lists.
[X] Wrong: "The merge takes quadratic time because it compares nodes multiple times."
[OK] Correct: Each node is visited only once, so comparisons happen once per node, not repeatedly.
Understanding this linear time merge is a key skill for working with linked lists and sorting algorithms.
"What if the input lists were not sorted? How would the time complexity of merging change?"
Practice
Solution
Step 1: Understand the merge operation
Merging two sorted linked lists means combining their elements into one list that remains sorted.Step 2: Identify the goal
The goal is to create a new sorted linked list that contains all elements from both input lists in order.Final Answer:
To create a new sorted linked list containing all elements from both lists -> Option AQuick Check:
Merge = combine sorted lists [OK]
- Thinking merge reverses lists
- Confusing merge with finding max element
- Assuming merge removes duplicates
Solution
Step 1: Check struct syntax for linked list node
In C, a node contains data and a pointer to the next node. The pointer must be declared as 'struct Node* next;'.Step 2: Identify correct declaration
struct Node { int data; struct Node* next; }; correctly declares 'struct Node' with 'int data' and 'struct Node* next;'. struct Node { int data; Node* next; }; misses 'struct' keyword before Node*, struct Node { int data; struct Node next; }; incorrectly uses 'struct Node next;' (not a pointer), and struct Node { int data; struct Node* prev; }; uses 'prev' which is for doubly linked lists.Final Answer:
struct Node { int data; struct Node* next; }; -> Option AQuick Check:
Node struct needs pointer to next node [OK]
- Omitting 'struct' keyword before Node*
- Using node instead of pointer for next
- Confusing singly linked list with doubly linked list
List1: 1 -> 3 -> 5 -> NULL
List2: 2 -> 4 -> 6 -> NULL
Assuming the merge function merges correctly.
Solution
Step 1: Compare elements from both lists in order
Start with heads: 1 (List1) and 2 (List2). 1 < 2, so 1 goes first. Then compare 3 and 2, 2 < 3, so 2 goes next. Continue this way to merge in sorted order.Step 2: Build merged list step-by-step
Merged list: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> NULL.Final Answer:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> NULL -> Option CQuick Check:
Merge keeps sorted order [OK]
- Appending one list after the other without sorting
- Reversing the order accidentally
- Skipping nodes during merge
struct Node* merge(struct Node* l1, struct Node* l2) {
if (!l1) return l2;
if (!l2) return l1;
if (l1->data < l2->data) {
l1->next = merge(l1->next, l2);
return l1;
} else {
l2->next = merge(l1, l2->next);
return l2;
}
}What is the main issue if this function is called with two sorted lists?
Solution
Step 1: Analyze base cases
If one list is empty (!l1 or !l2), it correctly returns the other list.Step 2: Analyze recursive case
If l1->data < l2->data, it sets l1->next to the merge of the rest and returns l1. Otherwise, sets l2->next to merge(l1, l2->next) and returns l2. However, when l1->data == l2->data, the else branch is taken repeatedly without advancing l1, causing infinite recursion.Final Answer:
It causes infinite recursion when lists have equal elements -> Option DQuick Check:
Equal elements cause infinite recursion due to no advancement in l1 [OK]
- Thinking equal elements cause infinite recursion
- Believing it loses nodes on empty lists
- Assuming it reverses the list
List1: 1 -> 4 -> 7 -> NULL
List2: 2 -> 4 -> 6 -> 8 -> NULL
Write the merged sorted linked list after merging them and removing duplicate values.
Solution
Step 1: Merge lists in sorted order
Merge elements: 1, 2, 4, 4, 6, 7, 8.Step 2: Remove duplicate values
Remove one of the duplicate 4's to get: 1 -> 2 -> 4 -> 6 -> 7 -> 8 -> NULL.Final Answer:
1 -> 2 -> 4 -> 6 -> 7 -> 8 -> NULL -> Option BQuick Check:
Merge + remove duplicates = sorted unique list [OK]
- Leaving duplicates in merged list
- Appending lists without sorting
- Removing unique elements by mistake
Ready to prove it?
Pass the test and this pattern moves unknown
