Stack Concept and LIFO Principle in DSA Go - Time & Space Complexity
We want to understand how the time to add or remove items from a stack changes as the stack grows.
How does the stack handle operations when it gets bigger?
Analyze the time complexity of the following code snippet.
package main
import "fmt"
type Stack struct {
items []int
}
func (s *Stack) Push(item int) {
s.items = append(s.items, item)
}
func (s *Stack) Pop() int {
if len(s.items) == 0 {
return -1
}
last := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return last
}
func main() {
s := Stack{}
s.Push(10)
s.Push(20)
fmt.Println(s.Pop())
fmt.Println(s.Pop())
}
This code shows how to add (Push) and remove (Pop) items from a stack using a slice.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Adding or removing one item at the end of the slice.
- How many times: Each Push or Pop does this once per call, no loops inside.
Each Push or Pop takes about the same time no matter how many items are in the stack.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 1 operation per Push or Pop |
| 100 | 1 operation per Push or Pop |
| 1000 | 1 operation per Push or Pop |
Pattern observation: The time does not grow with the number of items; it stays constant.
Time Complexity: O(1)
This means adding or removing an item from the stack takes the same short time no matter how big the stack is.
[X] Wrong: "Pushing or popping takes longer as the stack grows because there are more items to check."
[OK] Correct: The stack only adds or removes the last item, so it does not look at other items. The operation time stays the same.
Knowing that stack operations are quick and constant time helps you explain why stacks are useful for tasks like undo actions or expression evaluation.
"What if we changed the stack to remove items from the front instead of the end? How would the time complexity change?"
Practice
Solution
Step 1: Understand LIFO meaning
LIFO stands for Last In, First Out, meaning the last item added to the stack is the first one removed.Step 2: Match with stack behavior
Stacks follow LIFO, so the last pushed element is popped first.Final Answer:
Last In, First Out - the last element added is the first to be removed -> Option AQuick Check:
LIFO = Last In, First Out [OK]
- Confusing LIFO with FIFO
- Thinking first added is removed first
- Mixing up stack with queue behavior
stack in Go?Solution
Step 1: Recall Go slice push syntax
In Go, stacks are often slices; to push, use append(slice, value).Step 2: Check options for correct syntax
Onlystack = append(stack, 5)correctly adds 5 to the stack slice.Final Answer:
stack = append(stack, 5) -> Option BQuick Check:
Go stack push uses append [OK]
- Using non-existent push method on slice
- Using add or insert which are invalid for slices
- Forgetting to assign append result back
stack := []int{}
stack = append(stack, 10)
stack = append(stack, 20)
stack = append(stack, 30)
last := stack[len(stack)-1]
stack = stack[:len(stack)-1]
fmt.Println(last)Solution
Step 1: Trace stack push operations
Elements 10, 20, 30 are pushed in order; stack is [10, 20, 30].Step 2: Pop last element
last = stack[len(stack)-1] gets 30; then stack is sliced to remove last element.Final Answer:
30 -> Option AQuick Check:
Last pushed element popped = 30 [OK]
- Printing first element instead of last
- Forgetting to slice stack after pop
- Confusing index for pop operation
stack := []int{1, 2, 3}
last := stack[len(stack)]
stack = stack[:len(stack)-1]
fmt.Println(last)Solution
Step 1: Check index used for popping
Indexing with stack[len(stack)] is invalid because slice indices go from 0 to len(stack)-1.Step 2: Identify error type
This causes an index out of range runtime error.Final Answer:
Index out of range error due to accessing stack[len(stack)] -> Option CQuick Check:
Index must be len(stack)-1, not len(stack) [OK]
- Using len(stack) as index
- Ignoring zero-based indexing
- Assuming code runs without error
Solution
Step 1: Pop all elements from original stack
Pop elements one by one and store them in a temporary slice to hold reversed order.Step 2: Push elements back to original stack
Push elements from temporary slice back to stack; this reverses the order due to LIFO.Final Answer:
Pop all elements into a temporary slice, then push them back in order -> Option DQuick Check:
Reversing stack needs pop then push back [OK]
- Pushing without popping does not reverse
- Discarding elements loses data
- Using queue is not stack operation
Ready to prove it?
Pass the test and this pattern moves unknown
