Peek Top Element of Stack in DSA Rust - Time & Space Complexity
We want to understand how long it takes to look at the top item of a stack.
How does the time needed change when the stack grows bigger?
Analyze the time complexity of the following code snippet.
struct Stack {
elements: Vec<i32>,
}
impl Stack {
fn peek(&self) -> Option<i32> {
self.elements.last().copied()
}
}
This code returns the top element of the stack without removing it.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Accessing the last element of a vector.
- How many times: Exactly once per peek call.
Looking at the top element takes the same time no matter how big the stack is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 1 |
| 100 | 1 |
| 1000 | 1 |
Pattern observation: The time stays constant as the stack grows.
Time Complexity: O(1)
This means peeking the top element takes the same short time no matter how many items are in the stack.
[X] Wrong: "Peeking takes longer if the stack is bigger because it has to check many elements."
[OK] Correct: Peeking only looks at the last element directly, so it does not depend on stack size.
Knowing that peek is a constant time operation helps you explain stack efficiency clearly and confidently.
"What if the stack was implemented using a linked list instead of a vector? How would the time complexity of peek change?"
Practice
peek operation do in a stack data structure?Solution
Step 1: Understand stack operations
A stack stores elements in a last-in, first-out order. Common operations include push, pop, and peek.Step 2: Define peek operation
Peek returns the top element without removing it, allowing you to see the current top value safely.Final Answer:
Returns the top element without removing it -> Option AQuick Check:
Peek = top element without removal [OK]
- Confusing peek with pop operation
- Thinking peek adds elements
- Assuming peek checks emptiness
Vec<i32> named stack?Solution
Step 1: Understand Rust Vec methods for stack
In Rust,Veccan be used as a stack.pop()removes and returns the last element,last()returns a reference to the last element without removing it.Step 2: Identify correct peek method
Peek means to see the top element without removing it, sostack.last()is correct.stack.pop()removes it,stack[0]accesses the first element, andstack.first()returns the first element, not the top.Final Answer:
let top = stack.last(); -> Option AQuick Check:
Peek = stack.last() [OK]
- Using pop() which removes element
- Accessing first() instead of last()
- Using index 0 which is bottom of stack
let mut stack = vec![10, 20, 30];
if let Some(top) = stack.last() {
println!("{}", top);
} else {
println!("Stack is empty");
}Solution
Step 1: Understand stack contents and last()
The stack vector contains [10, 20, 30]. The last element is 30.Step 2: Trace the if let statement
Thestack.last()returns Some(&30), so the if block prints 30.Final Answer:
30 -> Option BQuick Check:
stack.last() = 30 [OK]
- Printing bottom element instead of top
- Confusing last() with pop() output
- Assuming stack is empty
let stack = vec![1, 2, 3];
let top = stack.pop().unwrap();
println!("Top element: {}", top);Solution
Step 1: Check mutability for pop()
pop() removes the last element, so the vector must be mutable. Here, stack is immutable.Step 2: Fix by making stack mutable
Changelet stack = vec![1, 2, 3];tolet mut stack = vec![1, 2, 3];to allow pop().Final Answer:
stack should be mutable to use pop() -> Option DQuick Check:
pop() needs mutable stack [OK]
- Ignoring mut keyword error
- Confusing pop() with peek operation
- Assuming unwrap() always safe
Vec<i32>, write a Rust function peek_top that returns the top element as Option<i32> without removing it. What is the correct implementation?Solution
Step 1: Understand function requirements
The function must peek without removing, so it should borrow stack immutably and return Option<i32>.Step 2: Analyze options
fn peek_top(stack: &Vec<i32>) -> Option<i32> { stack.last().copied() } usesstack.last().copied()which returns Option<i32> by copying the reference. fn peek_top(stack: &mut Vec<i32>) -> Option<i32> { stack.pop() } removes element (pop), fn peek_top(stack: &Vec<i32>) -> i32 { *stack.last().unwrap() } unwraps and returns i32 (not Option), fn peek_top(stack: Vec<i32>) -> Option<i32> { stack.first().copied() } uses first() which is bottom element.Final Answer:
fn peek_top(stack: &Vec<i32>) -> Option<i32> { stack.last().copied() } -> Option CQuick Check:
Peek returns Option with copied last element [OK]
- Using pop() which removes element
- Returning i32 instead of Option<i32>
- Accessing first() instead of last()
Ready to prove it?
Pass the test and this pattern moves unknown
