Queue Concept and FIFO Principle in DSA Go - Time & Space Complexity
We want to understand how the time to add or remove items from a queue changes as the queue grows.
How does the queue handle operations when it has more items?
Analyze the time complexity of the following code snippet.
package main
import "fmt"
type Queue struct {
items []int
}
func (q *Queue) Enqueue(val int) {
q.items = append(q.items, val)
}
func (q *Queue) Dequeue() int {
val := q.items[0]
q.items = q.items[1:]
return val
}
func main() {
q := Queue{}
q.Enqueue(1)
q.Enqueue(2)
fmt.Println(q.Dequeue())
fmt.Println(q.Dequeue())
}
This code adds items to the end of the queue and removes items from the front, following FIFO.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Adding to the end and removing from the front of the slice.
- How many times: Each enqueue or dequeue runs once per call, but dequeue shifts the slice which can involve copying elements.
As the queue grows, adding items stays quick, but removing items requires shifting remaining elements.
| Input Size (n) | Approx. Operations for Dequeue |
|---|---|
| 10 | About 9 shifts |
| 100 | About 99 shifts |
| 1000 | About 999 shifts |
Pattern observation: The number of shifts grows linearly with the queue size, making dequeue slower as the queue grows.
Time Complexity: O(n) for dequeue, O(1) for enqueue
This means adding is fast and constant time, but removing takes longer as the queue grows because elements shift.
[X] Wrong: "Both enqueue and dequeue always take constant time."
[OK] Correct: Removing from the front requires shifting all other elements, so it takes longer when the queue is bigger.
Understanding how queue operations scale helps you explain trade-offs and choose the right data structure in real projects.
What if we used a linked list instead of a slice for the queue? How would the time complexity change?
Practice
Solution
Step 1: Understand FIFO meaning
FIFO means the first element that enters the queue is the first to leave.Step 2: Match FIFO to queue behavior
Queues follow FIFO, so the first added element is removed first.Final Answer:
First In, First Out - the first element added is the first removed -> Option BQuick Check:
FIFO = First In, First Out [OK]
- Confusing FIFO with LIFO
- Thinking last added is removed first
- Mixing stack behavior with queue
Solution
Step 1: Identify slice declaration for queue
In Go, a queue can be represented as a slice, initialized as empty with []int{}.Step 2: Check options for correct slice syntax
queue := []int{} uses slice literal syntax to create an empty int slice, suitable for queue.Final Answer:
queue := []int{} -> Option AQuick Check:
Slice queue declaration = queue := []int{} [OK]
- Using map instead of slice
- Declaring queue as single int variable
- Using var without initialization for slice
package main
import "fmt"
func main() {
queue := []int{10, 20, 30}
// Dequeue operation
first := queue[0]
queue = queue[1:]
fmt.Println(first)
fmt.Println(queue)
}Solution
Step 1: Identify dequeue operation
The first element 10 is stored in 'first', then queue is sliced from index 1 onward.Step 2: Determine output values
Printing 'first' outputs 10; printing 'queue' outputs remaining slice [20 30].Final Answer:
10 [20 30] -> Option CQuick Check:
Dequeue removes first element = 10, queue left = [20 30] [OK]
- Printing old queue without slicing
- Confusing index positions
- Assuming queue unchanged after dequeue
package main
func main() {
queue := []int{1, 2, 3}
queue[3] = 4
}Solution
Step 1: Analyze slice indexing
Slice 'queue' has length 3 with indices 0,1,2; index 3 is out of range.Step 2: Understand how to add elements
To add elements, use append(queue, 4) instead of direct index assignment.Final Answer:
Index out of range error because slice index 3 does not exist -> Option DQuick Check:
Accessing queue[3] invalid for length 3 slice [OK]
- Trying to assign beyond slice length
- Forgetting to use append for enqueue
- Assuming slice auto-expands on index assignment
func enqueueMultiple(queue []int, elements []int) []int {
// Fill in
}Solution
Step 1: Understand enqueue multiple elements
To add multiple elements preserving order, append all new elements at the end of queue.Step 2: Check code options for correct append usage
return append(queue, elements...) uses append(queue, elements...) which adds all elements at the end in order.Final Answer:
return append(queue, elements...) -> Option AQuick Check:
Appending elements at end preserves FIFO enqueue order [OK]
- Appending new elements before queue (wrong order)
- Replacing queue instead of appending
- Appending elements one by one at front
Ready to prove it?
Pass the test and this pattern moves unknown
