Challenge - 5 Problems
Doubly Linked List Deletion Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediateOutput after deleting the first node from a doubly linked list
What is the printed state of the doubly linked list after deleting the first node?
DSA Rust
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct Node { data: i32, prev: Option<Rc<RefCell<Node>>>, next: Option<Rc<RefCell<Node>>>, } #[derive(Debug)] struct DoublyLinkedList { head: Option<Rc<RefCell<Node>>>, tail: Option<Rc<RefCell<Node>>>, } impl DoublyLinkedList { fn new() -> Self { DoublyLinkedList { head: None, tail: None } } fn append(&mut self, data: i32) { let new_node = Rc::new(RefCell::new(Node { data, prev: None, next: None })); match self.tail.take() { Some(old_tail) => { old_tail.borrow_mut().next = Some(new_node.clone()); new_node.borrow_mut().prev = Some(old_tail); self.tail = Some(new_node); } None => { self.head = Some(new_node.clone()); self.tail = Some(new_node); } } } fn delete_from_beginning(&mut self) { if let Some(old_head) = self.head.take() { let next_node = old_head.borrow_mut().next.take(); match next_node { Some(next) => { next.borrow_mut().prev = None; self.head = Some(next); } None => { self.tail = None; } } } } fn print_list(&self) { let mut current = self.head.clone(); let mut result = vec![]; while let Some(node) = current { result.push(node.borrow().data); current = node.borrow().next.clone(); } let output = result.iter().map(|d| d.to_string()).collect::<Vec<_>>().join(" <-> "); println!("{} <-> null", output); } } fn main() { let mut dll = DoublyLinkedList::new(); dll.append(10); dll.append(20); dll.append(30); dll.delete_from_beginning(); dll.print_list(); }
Attempts:
2 left
💡 Hint
Deleting from the beginning removes the first node and updates the head pointer.
✗ Incorrect
The list initially is 10 <-> 20 <-> 30 <-> null. After deleting the first node (10), the new head is 20, so the list becomes 20 <-> 30 <-> null.
❓ Predict Output
intermediateOutput after deleting from an empty doubly linked list
What is the printed state of the doubly linked list after attempting to delete from an empty list?
DSA Rust
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct Node { data: i32, prev: Option<Rc<RefCell<Node>>>, next: Option<Rc<RefCell<Node>>>, } #[derive(Debug)] struct DoublyLinkedList { head: Option<Rc<RefCell<Node>>>, tail: Option<Rc<RefCell<Node>>>, } impl DoublyLinkedList { fn new() -> Self { DoublyLinkedList { head: None, tail: None } } fn delete_from_beginning(&mut self) { if let Some(old_head) = self.head.take() { let next_node = old_head.borrow_mut().next.take(); match next_node { Some(next) => { next.borrow_mut().prev = None; self.head = Some(next); } None => { self.tail = None; } } } } fn print_list(&self) { let mut current = self.head.clone(); let mut result = vec![]; while let Some(node) = current { result.push(node.borrow().data); current = node.borrow().next.clone(); } if result.is_empty() { println!("null"); } else { let output = result.iter().map(|d| d.to_string()).collect::<Vec<_>>().join(" <-> "); println!("{} <-> null", output); } } } fn main() { let mut dll = DoublyLinkedList::new(); dll.delete_from_beginning(); dll.print_list(); }
Attempts:
2 left
💡 Hint
Deleting from an empty list should not crash and the list remains empty.
✗ Incorrect
Since the list is empty, deleting from the beginning does nothing. The printed output is 'null' indicating an empty list.
🔧 Debug
advancedIdentify the error in deleting the first node from a doubly linked list
What error will this code produce when deleting the first node?
DSA Rust
struct Node {
data: i32,
prev: Option<Box<Node>>,
next: Option<Box<Node>>,
}
struct DoublyLinkedList {
head: Option<Box<Node>>,
tail: Option<Box<Node>>,
}
impl DoublyLinkedList {
fn delete_from_beginning(&mut self) {
if let Some(mut old_head) = self.head.take() {
self.head = old_head.next.take();
if let Some(ref mut new_head) = self.head {
new_head.prev = None;
} else {
self.tail = None;
}
}
}
}
fn main() {
let mut dll = DoublyLinkedList { head: None, tail: None };
dll.delete_from_beginning();
}Attempts:
2 left
💡 Hint
Check ownership and move semantics when taking old_head and accessing next.
✗ Incorrect
The code moves old_head out of self.head, then tries to access old_head.next after move, causing use of moved value error.
❓ Predict Output
advancedOutput after multiple deletions from beginning of doubly linked list
What is the printed state of the doubly linked list after deleting the first node twice?
DSA Rust
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct Node { data: i32, prev: Option<Rc<RefCell<Node>>>, next: Option<Rc<RefCell<Node>>>, } #[derive(Debug)] struct DoublyLinkedList { head: Option<Rc<RefCell<Node>>>, tail: Option<Rc<RefCell<Node>>>, } impl DoublyLinkedList { fn new() -> Self { DoublyLinkedList { head: None, tail: None } } fn append(&mut self, data: i32) { let new_node = Rc::new(RefCell::new(Node { data, prev: None, next: None })); match self.tail.take() { Some(old_tail) => { old_tail.borrow_mut().next = Some(new_node.clone()); new_node.borrow_mut().prev = Some(old_tail); self.tail = Some(new_node); } None => { self.head = Some(new_node.clone()); self.tail = Some(new_node); } } } fn delete_from_beginning(&mut self) { if let Some(old_head) = self.head.take() { let next_node = old_head.borrow_mut().next.take(); match next_node { Some(next) => { next.borrow_mut().prev = None; self.head = Some(next); } None => { self.tail = None; } } } } fn print_list(&self) { let mut current = self.head.clone(); let mut result = vec![]; while let Some(node) = current { result.push(node.borrow().data); current = node.borrow().next.clone(); } if result.is_empty() { println!("null"); } else { let output = result.iter().map(|d| d.to_string()).collect::<Vec<_>>().join(" <-> "); println!("{} <-> null", output); } } } fn main() { let mut dll = DoublyLinkedList::new(); dll.append(5); dll.append(15); dll.append(25); dll.delete_from_beginning(); dll.delete_from_beginning(); dll.print_list(); }
Attempts:
2 left
💡 Hint
Each deletion removes the current head node and updates the head pointer.
✗ Incorrect
After first deletion, list is 15 <-> 25 <-> null. After second deletion, list is 25 <-> null.
🧠 Conceptual
expertWhy is it important to update the 'prev' pointer of the new head when deleting from the beginning?
In a doubly linked list, after deleting the first node, why must the 'prev' pointer of the new head be set to None?
Attempts:
2 left
💡 Hint
Think about how nodes are connected backward and what happens if the old head is removed.
✗ Incorrect
Setting the 'prev' pointer of the new head to None removes the backward link to the deleted node, preventing dangling references and potential memory leaks.
