What if your stack could magically grow whenever you need more space, without you lifting a finger?
Why Dynamic Stack Using Resizable Array in DSA Rust?
Imagine you have a stack of plates at home. You want to add more plates, but your shelf has a fixed size. When the shelf is full, you have to find a new shelf or manually move plates around to make space.
Using a fixed-size array for a stack means you can run out of space quickly. You must guess the size in advance, and if you guess wrong, you waste space or run out. Manually resizing means copying all plates to a new shelf, which is slow and error-prone.
A dynamic stack with a resizable array automatically grows when needed. It starts small and doubles its size when full, so you never run out of space. This makes adding plates easy and fast without manual moving.
let mut stack = [0; 5]; // fixed size let mut top = 0; // Can't push if full if top < 5 { stack[top] = value; top += 1; }
let mut stack = Vec::new(); stack.push(value); // automatically resizes
You can build flexible stacks that grow as needed, making your programs handle more data smoothly without crashes or wasted space.
Think of a web browser's back button history. It needs to remember pages you visited, but you don't know how many. A dynamic stack lets the browser store all pages you visit without limits.
Fixed-size stacks limit how much data you can store.
Dynamic stacks resize automatically to hold more items.
This makes your programs more flexible and reliable.
Practice
Solution
Step 1: Understand fixed vs dynamic size
A fixed-size array stack has a set capacity that cannot change during runtime, limiting the number of elements it can hold.Step 2: Analyze dynamic stack behavior
A dynamic stack using a resizable array can increase or decrease its capacity by resizing the underlying array, allowing it to handle more or fewer elements as needed.Final Answer:
It can grow or shrink in size as needed during runtime. -> Option BQuick Check:
Dynamic resizing = flexible size [OK]
- Thinking dynamic stack has fixed size
- Confusing linked list with array stack
- Assuming no resizing needed
Solution
Step 1: Understand vector capacity and reserve method
The vector's capacity is the total space allocated. To double capacity, we add capacity() more space using reserve(capacity()).Step 2: Check each option's reserve argument
if stack.len() == stack.capacity() { stack.reserve(stack.capacity()); } reserves current capacity again, doubling it. Others reserve too little or zero, not doubling.Final Answer:
if stack.len() == stack.capacity() { stack.reserve(stack.capacity()); } -> Option AQuick Check:
Reserve current capacity to double [OK]
- Reserving fixed small number instead of doubling
- Using zero in reserve causing no growth
- Confusing len() with capacity()
struct Stack {
data: Vec<i32>,
}
impl Stack {
fn new() -> Self {
Stack { data: Vec::new() }
}
fn push(&mut self, val: i32) {
self.data.push(val);
}
fn pop(&mut self) -> Option<i32> {
self.data.pop()
}
fn print(&self) {
for v in self.data.iter().rev() {
print!("{} -> ", v);
}
println!("null");
}
}
fn main() {
let mut stack = Stack::new();
stack.push(10);
stack.push(20);
stack.pop();
stack.push(30);
stack.print();
}Solution
Step 1: Trace push and pop operations
Push 10: stack = [10]; Push 20: stack = [10, 20]; Pop: removes 20, stack = [10]; Push 30: stack = [10, 30]Step 2: Understand print order
Print iterates in reverse order: top is last element pushed, so prints 30 then 10, then null.Final Answer:
30 -> 10 -> null -> Option DQuick Check:
Stack top to bottom = 30, 10 [OK]
- Forgetting pop removes last element
- Printing in wrong order (not reversed)
- Confusing push order with print order
fn push(&mut self, val: i32) {
if self.data.len() == self.data.capacity() {
self.data.reserve(self.data.len());
}
self.data.push(val);
}Solution
Step 1: Check the resizing logic
When self.data.len() == self.data.capacity(), the stack is full. reserve(self.data.len()) requests additional space for len() more elements. Since len() == capacity() at this point, it doubles the capacity.Step 2: Verify correctness
reserve(self.data.capacity()) would be equivalent here. The code safely resizes before push, preventing issues, and works correctly. (Rust Vec::push auto-resizes too, but manual is valid.)Final Answer:
No bug; code works correctly -> Option CQuick Check:
len() == capacity() when called, so doubles [OK]
- Reserving too little space (e.g., reserve(1))
- Calling reserve after push causing potential panic
- Assuming push auto-resizes without manual check
Solution
Step 1: Understand shrinking condition
We want to shrink when elements are less than 25% of capacity to save memory.Step 2: Use shrink_to method correctly
Calling shrink_to(len()) reduces capacity to fit current elements, freeing unused space.Step 3: Analyze options
After pop, if len() < capacity() / 4, call data.shrink_to(len()) correctly checks condition and calls shrink_to(len()). Others either use wrong methods or do nothing.Final Answer:
After pop, if len() < capacity() / 4, call data.shrink_to(len()) -> Option AQuick Check:
Shrink when quarter full using shrink_to(len()) [OK]
- Using reserve instead of shrink_to for shrinking
- Shrinking at half capacity instead of quarter
- Assuming automatic shrinking without code
Ready to prove it?
Pass the test and this pattern moves unknown
