Bird
Raised Fist0
DSA Rustprogramming~20 mins

Delete Node at End in DSA Rust - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Delete Node at End Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output after deleting the last node in a singly linked list
What is the printed state of the linked list after deleting the last node?
DSA Rust
struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

struct LinkedList {
    head: Option<Box<Node>>,
}

impl LinkedList {
    fn new() -> Self {
        LinkedList { head: None }
    }

    fn append(&mut self, data: i32) {
        let new_node = Box::new(Node { data, next: None });
        match self.head.as_mut() {
            None => self.head = Some(new_node),
            Some(mut node) => {
                while let Some(ref mut next_node) = node.next {
                    node = next_node;
                }
                node.next = Some(new_node);
            }
        }
    }

    fn delete_end(&mut self) {
        if self.head.is_none() {
            return;
        }
        if self.head.as_ref().unwrap().next.is_none() {
            self.head = None;
            return;
        }
        let mut current = self.head.as_mut().unwrap();
        while current.next.as_ref().unwrap().next.is_some() {
            current = current.next.as_mut().unwrap();
        }
        current.next = None;
    }

    fn print_list(&self) {
        let mut current = self.head.as_ref();
        while let Some(node) = current {
            print!("{} -> ", node.data);
            current = node.next.as_ref();
        }
        println!("null");
    }
}

fn main() {
    let mut list = LinkedList::new();
    list.append(10);
    list.append(20);
    list.append(30);
    list.delete_end();
    list.print_list();
}
A10 -> 20 -> 30 -> null
Bnull
C10 -> 20 -> null
D10 -> null
Attempts:
2 left
💡 Hint
Deleting the last node removes the node with value 30.
❓ Predict Output
intermediate
2:00remaining
Output after deleting the last node from a single-node list
What is the printed state of the linked list after deleting the last node when the list has only one node?
DSA Rust
struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

struct LinkedList {
    head: Option<Box<Node>>,
}

impl LinkedList {
    fn new() -> Self {
        LinkedList { head: None }
    }

    fn append(&mut self, data: i32) {
        let new_node = Box::new(Node { data, next: None });
        match self.head.as_mut() {
            None => self.head = Some(new_node),
            Some(mut node) => {
                while let Some(ref mut next_node) = node.next {
                    node = next_node;
                }
                node.next = Some(new_node);
            }
        }
    }

    fn delete_end(&mut self) {
        if self.head.is_none() {
            return;
        }
        if self.head.as_ref().unwrap().next.is_none() {
            self.head = None;
            return;
        }
        let mut current = self.head.as_mut().unwrap();
        while current.next.as_ref().unwrap().next.is_some() {
            current = current.next.as_mut().unwrap();
        }
        current.next = None;
    }

    fn print_list(&self) {
        let mut current = self.head.as_ref();
        while let Some(node) = current {
            print!("{} -> ", node.data);
            current = node.next.as_ref();
        }
        println!("null");
    }
}

fn main() {
    let mut list = LinkedList::new();
    list.append(100);
    list.delete_end();
    list.print_list();
}
Anull
B100 -> null
C100 -> 100 -> null
DError: Cannot delete from single-node list
Attempts:
2 left
💡 Hint
Deleting the last node from a single-node list results in an empty list.
🔧 Debug
advanced
2:00remaining
Identify the error in deleting the last node
What error will this code produce when deleting the last node from an empty list?
DSA Rust
struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

struct LinkedList {
    head: Option<Box<Node>>,
}

impl LinkedList {
    fn delete_end(&mut self) {
        let mut current = self.head.as_mut().unwrap();
        while current.next.as_ref().unwrap().next.is_some() {
            current = current.next.as_mut().unwrap();
        }
        current.next = None;
    }
}

fn main() {
    let mut list = LinkedList { head: None };
    list.delete_end();
}
ACompilation error: missing lifetime specifier
BNo error, code runs successfully
CTypeError: cannot borrow as mutable
Dpanic at 'called `Option::unwrap()` on a `None` value'
Attempts:
2 left
💡 Hint
The code calls unwrap on None without checking if head is None.
🧠 Conceptual
advanced
2:00remaining
Why is a mutable reference needed to delete the last node?
In Rust, why do we need a mutable reference to traverse and delete the last node in a singly linked list?
ABecause Rust does not allow any references to linked list nodes
BBecause we need to modify the next pointer of the second last node to None
CBecause mutable references prevent memory leaks automatically
DBecause immutable references allow changing the list structure
Attempts:
2 left
💡 Hint
Deleting the last node requires changing the pointer of the previous node.
❓ Predict Output
expert
3:00remaining
Output after multiple deletions at the end
What is the printed state of the linked list after deleting the last node three times from the initial list 5 -> 15 -> 25 -> 35 -> 45 -> null?
DSA Rust
struct Node {
    data: i32,
    next: Option<Box<Node>>,
}

struct LinkedList {
    head: Option<Box<Node>>,
}

impl LinkedList {
    fn new() -> Self {
        LinkedList { head: None }
    }

    fn append(&mut self, data: i32) {
        let new_node = Box::new(Node { data, next: None });
        match self.head.as_mut() {
            None => self.head = Some(new_node),
            Some(mut node) => {
                while let Some(ref mut next_node) = node.next {
                    node = next_node;
                }
                node.next = Some(new_node);
            }
        }
    }

    fn delete_end(&mut self) {
        if self.head.is_none() {
            return;
        }
        if self.head.as_ref().unwrap().next.is_none() {
            self.head = None;
            return;
        }
        let mut current = self.head.as_mut().unwrap();
        while current.next.as_ref().unwrap().next.is_some() {
            current = current.next.as_mut().unwrap();
        }
        current.next = None;
    }

    fn print_list(&self) {
        let mut current = self.head.as_ref();
        while let Some(node) = current {
            print!("{} -> ", node.data);
            current = node.next.as_ref();
        }
        println!("null");
    }
}

fn main() {
    let mut list = LinkedList::new();
    list.append(5);
    list.append(15);
    list.append(25);
    list.append(35);
    list.append(45);
    list.delete_end();
    list.delete_end();
    list.delete_end();
    list.print_list();
}
A5 -> 15 -> null
B5 -> 15 -> 25 -> null
C5 -> 15 -> 25 -> 35 -> null
Dnull
Attempts:
2 left
💡 Hint
Each deletion removes the last node, so after three deletions, three nodes are removed.

Practice

(1/5)
1. What does the operation Delete Node at End do in a linked list?
easy
A. Adds a new node at the end of the linked list
B. Removes the last node from the linked list
C. Removes the first node from the linked list
D. Searches for a node at the end of the linked list

Solution

  1. Step 1: Understand the linked list structure

    A linked list is a chain of nodes where each node points to the next one.
  2. Step 2: Identify the effect of deleting the last node

    Deleting the last node means removing the node that has no next node, effectively shortening the list by one node at the end.
  3. Final Answer:

    Removes the last node from the linked list -> Option B
  4. Quick Check:

    Delete Node at End = Remove last node [OK]
Hint: Deleting at end always removes the last node [OK]
Common Mistakes:
  • Confusing delete at end with delete at start
  • Thinking it adds a node instead of removing
  • Assuming it searches without deleting
2. Which of the following Rust code snippets correctly deletes the last node of a singly linked list?
easy
A. fn delete_end(head: &mut Option) { if head.is_none() { return; } let mut current = head.as_mut().unwrap(); while current.next.as_ref().unwrap().next.is_some() { current = current.next.as_mut().unwrap(); } current.next = None; }
B. fn delete_end(head: &mut Option) { *head = None; }
C. fn delete_end(head: &mut Option) { let mut current = head.as_mut().unwrap(); current.next = None; }
D. fn delete_end(head: &mut Option) { while head.is_some() { head = head.unwrap().next; } }

Solution

  1. Step 1: Analyze the code logic for deleting last node

    fn delete_end(head: &mut Option) { if head.is_none() { return; } let mut current = head.as_mut().unwrap(); while current.next.as_ref().unwrap().next.is_some() { current = current.next.as_mut().unwrap(); } current.next = None; } traverses the list until the second last node and sets its next to None, removing the last node.
  2. Step 2: Check other options for correctness

    fn delete_end(head: &mut Option) { *head = None; } deletes the entire list, not just last node. fn delete_end(head: &mut Option) { let mut current = head.as_mut().unwrap(); current.next = None; } incorrectly sets next of head only. fn delete_end(head: &mut Option) { while head.is_some() { head = head.unwrap().next; } } tries to reassign head incorrectly causing error.
  3. Final Answer:

    Option A code correctly deletes the last node -> Option A
  4. Quick Check:

    Traverse to second last node and set next to None [OK]
Hint: Traverse to second last node, then set next to None [OK]
Common Mistakes:
  • Setting head to None deletes whole list
  • Not checking for empty or single node list
  • Incorrectly reassigning head pointer
3. Given the Rust linked list code below, what will be the printed output after deleting the last node?
struct Node { val: i32, next: Option }
fn print_list(head: &Option) {
let mut current = head;
while let Some(node) = current {
print!("{} -> ", node.val);
current = &node.next;
}
println!("null");
}
fn main() {
let mut head = Some(Box::new(Node { val: 1, next: Some(Box::new(Node { val: 2, next: Some(Box::new(Node { val: 3, next: None })) })) }));
delete_end(&mut head);
print_list(&head);
}
fn delete_end(head: &mut Option) {
if head.is_none() { return; }
if head.as_ref().unwrap().next.is_none() { *head = None; return; }
let mut current = head.as_mut().unwrap();
while current.next.as_ref().unwrap().next.is_some() {
current = current.next.as_mut().unwrap();
}
current.next = None;
}
medium
A. null
B. 1 -> 2 -> 3 -> null
C. 1 -> 2 -> null
D. 1 -> null

Solution

  1. Step 1: Understand initial list and delete_end effect

    The list starts as 1 -> 2 -> 3 -> null. delete_end removes last node (3).
  2. Step 2: Trace print_list after deletion

    After deletion, list is 1 -> 2 -> null, so print_list outputs "1 -> 2 -> null".
  3. Final Answer:

    1 -> 2 -> null -> Option C
  4. Quick Check:

    Last node removed, list ends at 2 [OK]
Hint: Deleting last node removes final value from print output [OK]
Common Mistakes:
  • Expecting original list unchanged
  • Confusing print output format
  • Not handling single node list case
4. The following Rust function to delete the last node of a linked list causes a runtime panic. What is the error?
fn delete_end(head: &mut Option) {
let mut current = head.as_mut().unwrap();
while current.next.is_some() {
current = current.next.as_mut().unwrap();
}
current.next = None;
}
medium
A. It panics because it sets current to None instead of current.next
B. It panics because it modifies head directly without checking
C. It panics because it never stops the loop
D. It panics because it tries to unwrap None when list is empty

Solution

  1. Step 1: Locate the unwrap without check

    let mut current = head.as_mut().unwrap(); executes without prior if head.is_none() { return; }, causing panic on empty list when as_mut() returns None and unwrap panics.
  2. Step 2: Verify other options

    The code does not modify head directly. The while loop terminates when current.next.is_none(). Setting current.next = None after reaching the last node causes no panic.
  3. Final Answer:

    It panics because it tries to unwrap None when list is empty -> Option D
  4. Quick Check:

    head.as_mut().unwrap() without empty check [OK]
Hint: Check head.is_none() before any unwrap on head [OK]
Common Mistakes:
  • No check for empty list before unwrap
  • Not checking for empty or single node list
  • Looping until current.next is None instead of second last
5. You have a singly linked list with nodes containing values [10, 20, 30, 40]. Write a Rust function to delete the last node and return the updated list head. Which of the following implementations correctly handles the edge case when the list has only one node?
hard
A. fn delete_end(head: &mut Option) { if head.is_none() { return; } if head.as_ref().unwrap().next.is_none() { *head = None; return; } let mut current = head.as_mut().unwrap(); while current.next.as_ref().unwrap().next.is_some() { current = current.next.as_mut().unwrap(); } current.next = None; }
B. fn delete_end(head: &mut Option) { let mut current = head.as_mut().unwrap(); while current.next.is_some() { current = current.next.as_mut().unwrap(); } current = None; }
C. fn delete_end(head: &mut Option) { if head.is_none() { return; } let mut current = head.as_mut().unwrap(); while current.next.is_some() { current = current.next.as_mut().unwrap(); } current.next = None; }
D. fn delete_end(head: &mut Option) { *head = None; }

Solution

  1. Step 1: Check for empty and single node list

    fn delete_end(head: &mut Option) { if head.is_none() { return; } if head.as_ref().unwrap().next.is_none() { *head = None; return; } let mut current = head.as_mut().unwrap(); while current.next.as_ref().unwrap().next.is_some() { current = current.next.as_mut().unwrap(); } current.next = None; } correctly checks if list is empty or has only one node, setting head to None in that case.
  2. Step 2: Traverse to second last node and delete last

    fn delete_end(head: &mut Option) { if head.is_none() { return; } if head.as_ref().unwrap().next.is_none() { *head = None; return; } let mut current = head.as_mut().unwrap(); while current.next.as_ref().unwrap().next.is_some() { current = current.next.as_mut().unwrap(); } current.next = None; } then traverses to second last node and sets its next to None, deleting last node properly.
  3. Final Answer:

    Option A correctly handles all cases including single node list -> Option A
  4. Quick Check:

    Check empty/single node, then delete last node [OK]
Hint: Always check if list has one node before deleting last [OK]
Common Mistakes:
  • Not handling single node list causing panic
  • Setting current = None instead of current.next = None
  • Deleting entire list instead of last node
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