Bird
Raised Fist0
DSA Rustprogramming~20 mins

Queue Using Two Stacks in DSA Rust - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Two Stacks Queue Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of enqueue and dequeue operations
What is the printed state of the queue after these operations using two stacks?
DSA Rust
struct Queue {
    stack_in: Vec<i32>,
    stack_out: Vec<i32>,
}

impl Queue {
    fn new() -> Self {
        Queue { stack_in: Vec::new(), stack_out: Vec::new() }
    }

    fn enqueue(&mut self, val: i32) {
        self.stack_in.push(val);
    }

    fn dequeue(&mut self) -> Option<i32> {
        if self.stack_out.is_empty() {
            while let Some(x) = self.stack_in.pop() {
                self.stack_out.push(x);
            }
        }
        self.stack_out.pop()
    }

    fn print_queue(&mut self) {
        let mut temp = Vec::new();
        while let Some(x) = self.dequeue() {
            print!("{} -> ", x);
            temp.push(x);
        }
        println!("null");
        for x in temp.into_iter().rev() {
            self.stack_out.push(x);
        }
    }
}

fn main() {
    let mut q = Queue::new();
    q.enqueue(10);
    q.enqueue(20);
    q.enqueue(30);
    q.dequeue();
    q.enqueue(40);
    q.print_queue();
}
A20 -> 30 -> 40 -> null
B40 -> null
C30 -> 40 -> null
D10 -> 20 -> 30 -> 40 -> null
Attempts:
2 left
💡 Hint
Remember dequeue removes the oldest element, and enqueue adds to the newest.
🧠 Conceptual
intermediate
1:30remaining
Why use two stacks to implement a queue?
What is the main reason for using two stacks to implement a queue?
ATo allow random access to elements in the queue
BTo store elements in sorted order automatically
CTo reduce memory usage compared to a single stack
DTo reverse the order of elements twice, achieving FIFO behavior
Attempts:
2 left
💡 Hint
Think about how stacks and queues differ in order of removal.
🔧 Debug
advanced
1:30remaining
Identify the error in dequeue method
What error will occur when running this dequeue method if stack_out is empty and stack_in is also empty?
DSA Rust
fn dequeue(&mut self) -> i32 {
    if self.stack_out.is_empty() {
        while let Some(x) = self.stack_in.pop() {
            self.stack_out.push(x);
        }
    }
    self.stack_out.pop().unwrap()
}
APanic due to unwrap on None when both stacks are empty
BReturns None safely without panic
CCompilation error due to missing return type
DInfinite loop because stacks never empty
Attempts:
2 left
💡 Hint
What happens if you unwrap an Option that is None?
❓ Predict Output
advanced
2:00remaining
Final state of stacks after operations
After these operations, what is the content of stack_in and stack_out?
DSA Rust
let mut q = Queue::new();
q.enqueue(1);
q.enqueue(2);
q.enqueue(3);
q.dequeue();
q.enqueue(4);
q.dequeue();
Astack_in: [], stack_out: [3,4]
Bstack_in: [4], stack_out: [3]
Cstack_in: [4], stack_out: []
Dstack_in: [2,4], stack_out: [3]
Attempts:
2 left
💡 Hint
Trace each enqueue and dequeue carefully, noting when elements move between stacks.
🚀 Application
expert
1:30remaining
Time complexity of dequeue operation in two-stack queue
What is the amortized time complexity of the dequeue operation in a queue implemented using two stacks?
AO(log n) average time
BO(n) worst case for every dequeue
CO(1) amortized time
DO(n^2) in the worst case
Attempts:
2 left
💡 Hint
Consider how often elements move between stacks.

Practice

(1/5)
1. What is the main idea behind implementing a Queue Using Two Stacks?
easy
A. Use one stack for enqueue and another for dequeue operations
B. Use two stacks to perform only enqueue operations
C. Use two stacks to store elements in sorted order
D. Use two stacks to reverse the order twice to maintain queue order

Solution

  1. Step 1: Understand queue order

    A queue follows First-In-First-Out (FIFO) order, meaning the first element added is the first removed.
  2. Step 2: Use two stacks to reverse order twice

    One stack reverses the order when pushing elements, and the second stack reverses it back when popping, preserving FIFO.
  3. Final Answer:

    Use two stacks to reverse the order twice to maintain queue order -> Option D
  4. Quick Check:

    Two stacks reverse order twice = queue order [OK]
Hint: Two stacks reverse order twice to simulate queue [OK]
Common Mistakes:
  • Thinking both stacks store elements in sorted order
  • Using stacks only for enqueue or dequeue
  • Confusing stack order with queue order
2. Which of the following Rust code snippets correctly declares two stacks for implementing a queue?
easy
A. let mut stack1: Vec<i32> = Vec::new(); let mut stack2: Vec<i32> = Vec::new();
B. let stack1 = Vec<i32>; let stack2 = Vec<i32>;
C. let mut stack1 = Vec::new<i32>(); let mut stack2 = Vec::new<i32>();
D. let stack1: Vec = Vec::new(); let stack2: Vec = Vec::new();

Solution

  1. Step 1: Check correct Vec declaration syntax in Rust

    In Rust, to declare a mutable vector of i32, use: let mut stack: Vec<i32> = Vec::new();
  2. Step 2: Compare options with correct syntax

    let mut stack1: Vec<i32> = Vec::new(); let mut stack2: Vec<i32> = Vec::new(); matches the correct syntax exactly; others have syntax errors or missing mutability.
  3. Final Answer:

    let mut stack1: Vec<i32> = Vec::new(); let mut stack2: Vec<i32> = Vec::new(); -> Option A
  4. Quick Check:

    Correct Rust Vec declaration = let mut stack1: Vec<i32> = Vec::new(); let mut stack2: Vec<i32> = Vec::new(); [OK]
Hint: Use let mut stack: Vec<i32> = Vec::new() for mutable stacks [OK]
Common Mistakes:
  • Omitting mut keyword for mutable vectors
  • Incorrect generic syntax like Vec<i32> without parentheses
  • Using Vec::new<i32>() which is invalid
3. What will be the output of the following Rust code implementing a queue using two stacks?
struct Queue {
    stack1: Vec<i32>,
    stack2: Vec<i32>,
}

impl Queue {
    fn new() -> Self {
        Queue { stack1: Vec::new(), stack2: Vec::new() }
    }

    fn enqueue(&mut self, val: i32) {
        self.stack1.push(val);
    }

    fn dequeue(&mut self) -> Option<i32> {
        if self.stack2.is_empty() {
            while let Some(x) = self.stack1.pop() {
                self.stack2.push(x);
            }
        }
        self.stack2.pop()
    }
}

fn main() {
    let mut q = Queue::new();
    q.enqueue(10);
    q.enqueue(20);
    q.enqueue(30);
    println!("{:?}", q.dequeue());
    println!("{:?}", q.dequeue());
    q.enqueue(40);
    println!("{:?}", q.dequeue());
    println!("{:?}", q.dequeue());
}
medium
A. Some(10) Some(20) Some(30) Some(40)
B. Some(30) Some(20) Some(10) Some(40)
C. Some(10) Some(20) Some(40) None
D. None None None None

Solution

  1. Step 1: Trace enqueue operations

    Enqueue 10, 20, 30 pushes these onto stack1 in order: [10, 20, 30]
  2. Step 2: Trace dequeue operations

    First dequeue: stack2 empty, pop all from stack1 to stack2: stack2 = [30, 20, 10]. Pop from stack2 returns 10.
    Second dequeue: pop from stack2 returns 20.
    Enqueue 40: push 40 to stack1.
    Third dequeue: pop from stack2 returns 30.
    Fourth dequeue: stack2 empty, move 40 from stack1 to stack2, pop returns 40.
  3. Final Answer:

    Some(10) Some(20) Some(30) Some(40) -> Option A
  4. Quick Check:

    Queue order preserved by two stacks = Some(10) Some(20) Some(30) Some(40) [OK]
Hint: Dequeue empties stack2 by reversing stack1 first [OK]
Common Mistakes:
  • Assuming stack2 pops in same order as stack1
  • Not moving elements from stack1 to stack2 when stack2 is empty
  • Confusing order of elements after transfer
4. Identify the bug in this Rust code snippet for dequeue operation in a queue using two stacks:
fn dequeue(&mut self) -> Option<i32> {
    while let Some(x) = self.stack1.pop() {
        self.stack2.push(x);
    }
    self.stack2.pop()
}
medium
A. It uses pop() on stack1 instead of peek()
B. It moves elements from stack1 to stack2 every time, even if stack2 is not empty
C. It does not pop from stack2 after moving elements
D. It returns None always because stack2 is never filled

Solution

  1. Step 1: Analyze the dequeue logic

    The code moves all elements from stack1 to stack2 every dequeue call, regardless of stack2's state.
  2. Step 2: Identify correct behavior

    To maintain queue order efficiently, elements should be moved only if stack2 is empty. Otherwise, stack2's elements should be popped directly.
  3. Final Answer:

    It moves elements from stack1 to stack2 every time, even if stack2 is not empty -> Option B
  4. Quick Check:

    Move only if stack2 empty = It moves elements from stack1 to stack2 every time, even if stack2 is not empty [OK]
Hint: Move elements only if stack2 is empty during dequeue [OK]
Common Mistakes:
  • Moving elements every dequeue wastes time
  • Ignoring stack2's current elements
  • Not popping from stack2 after transfer
5. You want to implement a peek function for the queue using two stacks in Rust that returns the front element without removing it. Which approach correctly achieves this?
hard
A. Return the first element of stack1 without any stack transfers
B. Return the last element of stack1 directly without moving elements
C. If stack2 is empty, move all elements from stack1 to stack2, then return the last element of stack2 without popping
D. Pop an element from stack2 and push it back immediately to peek

Solution

  1. Step 1: Understand peek operation in queue using two stacks

    Peek should return the front element without removing it. The front is at the bottom of stack1 or top of stack2 after transfer.
  2. Step 2: Correct approach for peek

    If stack2 is empty, move all elements from stack1 to stack2 to reverse order. Then peek the last element of stack2 (top) without popping.
  3. Final Answer:

    If stack2 is empty, move all elements from stack1 to stack2, then return the last element of stack2 without popping -> Option C
  4. Quick Check:

    Peek uses stack2 top after transfer if empty = If stack2 is empty, move all elements from stack1 to stack2, then return the last element of stack2 without popping [OK]
Hint: Peek top of stack2 after transfer if empty [OK]
Common Mistakes:
  • Peeking stack1 directly ignores queue order
  • Popping to peek then pushing back wastes time
  • Ignoring stack2 state before peeking
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