Challenge - 5 Problems
Linked List Merge Sort Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediateOutput of Merge Sort on a Linked List
What is the printed state of the linked list after applying merge sort on the list 4 -> 2 -> 1 -> 3 -> null?
DSA Rust
struct ListNode {
val: i32,
next: Option<Box<ListNode>>,
}
fn print_list(head: &Option<Box<ListNode>>) {
let mut current = head;
while let Some(node) = current {
print!("{} -> ", node.val);
current = &node.next;
}
println!("null");
}
fn merge_sort(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
fn split(mut head: Option<Box<ListNode>>) -> (Option<Box<ListNode>>, Option<Box<ListNode>>) {
if head.is_none() || head.as_ref().unwrap().next.is_none() {
return (head, None);
}
let mut slow = &mut head;
let mut fast = &head.as_ref().unwrap().next;
while fast.is_some() && fast.as_ref().unwrap().next.is_some() {
slow = &mut slow.as_mut().unwrap().next;
fast = &fast.as_ref().unwrap().next.as_ref().unwrap().next;
}
let mid = slow.as_mut().unwrap().next.take();
(head, mid)
}
fn merge(l1: Option<Box<ListNode>>, l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
match (l1, l2) {
(Some(mut node1), Some(mut node2)) => {
if node1.val < node2.val {
let next = node1.next.take();
node1.next = merge(next, Some(node2));
Some(node1)
} else {
let next = node2.next.take();
node2.next = merge(Some(node1), next);
Some(node2)
}
}
(Some(node1), None) => Some(node1),
(None, Some(node2)) => Some(node2),
(None, None) => None,
}
}
if head.is_none() || head.as_ref().unwrap().next.is_none() {
return head;
}
let (left, right) = split(head);
let sorted_left = merge_sort(left);
let sorted_right = merge_sort(right);
merge(sorted_left, sorted_right)
}
fn main() {
let node4 = ListNode { val: 3, next: None };
let node3 = ListNode { val: 1, next: Some(Box::new(node4)) };
let node2 = ListNode { val: 2, next: Some(Box::new(node3)) };
let node1 = ListNode { val: 4, next: Some(Box::new(node2)) };
let head = Some(Box::new(node1));
let sorted_head = merge_sort(head);
print_list(&sorted_head);
}Attempts:
2 left
💡 Hint
Merge sort splits the list into halves and merges sorted halves.
✗ Incorrect
Merge sort on linked list sorts nodes in ascending order. The input list 4 -> 2 -> 1 -> 3 is sorted to 1 -> 2 -> 3 -> 4.
🧠 Conceptual
intermediateWhy use Merge Sort for Linked Lists?
Which reason best explains why merge sort is preferred for sorting linked lists over quicksort or heapsort?
Attempts:
2 left
💡 Hint
Think about how linked lists store data and how merge sort works.
✗ Incorrect
Merge sort works well with linked lists because it only rearranges pointers and does not need random access, unlike quicksort or heapsort.
🔧 Debug
advancedIdentify the Bug in Linked List Merge Function
What error will occur when running this merge function for two sorted linked lists?
fn merge(l1: Option>, l2: Option>) -> Option> {
match (l1, l2) {
(Some(mut node1), Some(mut node2)) => {
if node1.val <= node2.val {
node1.next = merge(node1.next, Some(node2));
Some(node1)
} else {
node2.next = merge(Some(node1), node2.next);
Some(node2)
}
}
(Some(node1), None) => Some(node1),
(None, Some(node2)) => Some(node2),
(None, None) => None,
}
}
Attempts:
2 left
💡 Hint
Check how ownership and borrowing are handled with mutable nodes.
✗ Incorrect
The code tries to move out of a mutable reference (node1.next) which is not allowed, causing a compilation error.
❓ Predict Output
advancedResult of Splitting a Linked List
Given the linked list 5 -> 8 -> 3 -> 7 -> null, what are the two lists after the split function is called?
DSA Rust
fn split(mut head: Option<Box<ListNode>>) -> (Option<Box<ListNode>>, Option<Box<ListNode>>) {
if head.is_none() || head.as_ref().unwrap().next.is_none() {
return (head, None);
}
let mut slow = &mut head;
let mut fast = &head.as_ref().unwrap().next;
while fast.is_some() && fast.as_ref().unwrap().next.is_some() {
slow = &mut slow.as_mut().unwrap().next;
fast = &fast.as_ref().unwrap().next.as_ref().unwrap().next;
}
let mid = slow.as_mut().unwrap().next.take();
(head, mid)
}
// Initial list: 5 -> 8 -> 3 -> 7 -> nullAttempts:
2 left
💡 Hint
The slow pointer stops before the middle node, splitting the list in half.
✗ Incorrect
The split function divides the list into two halves: first half 5 -> 8 and second half 3 -> 7.
🚀 Application
expertNumber of Recursive Calls in Merge Sort
For a linked list with 8 nodes, how many total recursive calls to merge_sort will be made during the full sort process?
Attempts:
2 left
💡 Hint
Think about how merge sort splits the list into halves recursively until single nodes.
✗ Incorrect
Merge sort on 8 nodes splits into 8 single nodes (base cases) plus all intermediate calls, totaling 15 calls.
