📖 Scenario: Imagine you are building a simple stack for a web browser's back button. The stack should grow automatically when more pages are visited.
🎯 Goal: Build a dynamic stack using a resizable array in Go. You will create the stack, add a capacity variable, implement push logic that resizes the array when full, and finally print the stack contents.
📋 What You'll Learn
Create a slice called stack with initial capacity 2 and length 0
Create an integer variable called capacity set to 2
Write a push function that adds an element to stack and doubles capacity when full
Print the final stack contents after pushing 4 elements
💡 Why This Matters
🌍 Real World
Resizable stacks are used in browsers, undo features, and expression evaluation where the number of elements changes dynamically.
💼 Career
Understanding dynamic arrays and stack operations is fundamental for software development roles involving data structures and memory management.
Progress0 / 4 steps
1
Create the initial stack slice
Create a slice called stack of type int with length 0 and capacity 2.
DSA Go
Hint
Use make([]int, 0, 2) to create a slice with length 0 and capacity 2.
2
Add capacity variable
Add an integer variable called capacity and set it to 2 below the stack slice.
DSA Go
Hint
Just create a variable capacity and assign 2.
3
Implement push function with resizing
Write a function called push that takes an integer val, a slice stack, and an integer capacity. Inside push, if the length of stack equals capacity, double capacity and create a new slice with the new capacity, copy old elements, then append val. Return the updated stack and capacity. Call push four times with values 10, 20, 30, 40, updating stack and capacity each time.
DSA Go
Hint
Check if len(stack) == capacity. If yes, double capacity and copy elements to a new slice before appending.
4
Print the final stack contents
Add a fmt.Println(stack) statement at the end of main to print the final contents of stack.
DSA Go
Hint
Use fmt.Println(stack) to print the slice contents.
Practice
(1/5)
1. What is the main advantage of using a dynamic stack implemented with a resizable array compared to a fixed-size array stack?
easy
A. It can grow or shrink automatically as elements are pushed or popped.
A fixed-size array stack cannot grow beyond its initial capacity, causing overflow if too many elements are pushed.
Step 2: Understand dynamic stack behavior
A dynamic stack with a resizable array automatically increases or decreases its size when needed, avoiding overflow and wasting less memory.
Final Answer:
It can grow or shrink automatically as elements are pushed or popped. -> Option A
Quick Check:
Dynamic resizing = Automatic growth/shrink [OK]
Hint: Dynamic arrays resize automatically on overflow or underflow [OK]
Common Mistakes:
Thinking dynamic stack has fixed size
Confusing linked list stack with array stack
Assuming no resizing is needed
2. Which of the following Go code snippets correctly doubles the size of the stack's underlying array when it is full?
easy
A. stack.data = append(stack.data, make([]int, len(stack.data))...)
B. newData := make([]int, len(stack.data)*2); copy(newData, stack.data); stack.data = newData
C. stack.data = stack.data[:len(stack.data)*2]
D. stack.data = make([]int, len(stack.data)/2)
Solution
Step 1: Understand how to resize an array in Go
Go slices cannot be resized directly; we create a new slice with double capacity and copy old elements.
Step 2: Check each option
newData := make([]int, len(stack.data)*2); copy(newData, stack.data); stack.data = newData creates a new slice double the size, copies old data, and assigns it back, which is correct resizing.
Initial data slice size is 2, size=0. Push 10 at index 0, size=1; Push 20 at index 1, size=2.
Step 2: Push 30 triggers resize
Since size == len(data), create newData with size 4, copy old data, assign newData. Then add 30 at index 2, size=3.
Step 3: Print slice up to size
Print data[:3] which contains [10 20 30].
Final Answer:
[10 20 30] -> Option C
Quick Check:
Resize + push = [10 20 30] [OK]
Hint: Resize before push when full, then add element [OK]
Common Mistakes:
Forgetting to resize before push
Printing full data slice including zeros
Index out of range by pushing without resize
4. The following Go code for popping from a dynamic stack sometimes causes a runtime error. What is the bug?
func (s *Stack) Pop() int {
s.size--
val := s.data[s.size]
if s.size < len(s.data)/4 {
newData := make([]int, len(s.data)/2)
copy(newData, s.data[:s.size])
s.data = newData
}
return val
}
medium
A. Decreasing size before checking if stack is empty causes negative index.
B. Resizing array to half size before copying causes data loss.
C. Copying data after resizing causes runtime error.
D. Returning val before resizing causes stale value.
Solution
Step 1: Analyze size decrement before access
Decreasing size before accessing data[s.size] can cause s.size to be negative if stack is empty.
Step 2: Understand runtime error cause
Accessing data with negative index causes runtime panic (index out of range).
Final Answer:
Decreasing size before checking if stack is empty causes negative index. -> Option A
Quick Check:
Pop decrements size before check = negative index [OK]
Hint: Check empty before decrementing size [OK]
Common Mistakes:
Not checking if stack is empty before pop
Resizing array incorrectly
Accessing data after size decrement without validation
5. You want to implement a dynamic stack in Go that shrinks its underlying array when the number of elements falls below one-fourth of the capacity, but never shrinks below a minimum capacity of 4. Which code snippet correctly implements this logic inside the Pop method?
hard
A. if s.size < len(s.data)/2 && len(s.data)/4 >= 4 { newData := make([]int, len(s.data)/4); copy(newData, s.data[:s.size]); s.data = newData }
B. if s.size < len(s.data)/4 { s.data = s.data[:len(s.data)/2] }
C. if s.size < 4 { s.data = make([]int, 4) }
D. if s.size < len(s.data)/4 && len(s.data)/2 >= 4 { newData := make([]int, len(s.data)/2); copy(newData, s.data[:s.size]); s.data = newData }
Solution
Step 1: Understand shrinking condition
Shrink when size < 1/4 capacity, but only if new capacity ≥ 4.
Step 2: Check each option
if s.size < len(s.data)/4 && len(s.data)/2 >= 4 { newData := make([]int, len(s.data)/2); copy(newData, s.data[:s.size]); s.data = newData } checks size < 1/4 capacity and new capacity ≥ 4, then resizes to half capacity correctly.