Stacks and Queues
Queue from Two Stacks
Implement queue behavior with an input stack and an output stack.
Algorithm
The replay uses the same three values in every language, so this Swift DSA implementation can be compared directly with the rest of the DSA track.
input stack
Enqueue pushes new values onto the input stack.
output stack
When the output stack is empty, transferring all input values reverses them into dequeue order.
Visual walkthrough
Basic Implementation
basic.swift
func render(_ values: [Int]) -> String {
values.map(String.init).joined(separator: " -> ")
}
var inStack: [Int] = []
var outStack: [Int] = []
for value in [10, 20, 30] { inStack.append(value) }
while !inStack.isEmpty { outStack.append(inStack.removeLast()) }
var removed: [Int] = []
while !outStack.isEmpty { removed.append(outStack.removeLast()) }
print(render(removed))
Complexity
- Time: O(1) amortized per operation
- Space: O(n)
Implementation notes
var inStack: [Int] = []andvar outStack: [Int] = []are mutable Swift arrays used as stack storage; the back of each array is the stack top.- Enqueue is the loop
for value in [10, 20, 30] { inStack.append(value) }, which appends eachIntto the input stack. - The transfer loop
while !inStack.isEmptyguardsremoveLast(), so the source has no optional return or sentinel path while moving values intooutStack. outStack.append(inStack.removeLast())reverses the input stack, changing[10, 20, 30]into output stack state[30, 20, 10].var removed: [Int] = []then collects dequeues withremoved.append(outStack.removeLast())whileoutStackis non-empty.- The trace records empty stacks,
inStack = [10, 20, 30], transfer toinStack = []andoutStack = [30, 20, 10], thenremoved = [10, 20, 30]withoutStack = []. render(_:)maps eachInttoStringand joins with" -> ", soprint(render(removed))outputs10 -> 20 -> 30.