Bird
Raised Fist0
DSA Goprogramming~5 mins

Min Stack Design in DSA Go - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Min Stack Design
O(1)
Understanding Time Complexity

We want to understand how fast the Min Stack operations run as the stack grows.

How does the time to push, pop, or get the minimum change with more elements?

Scenario Under Consideration

Analyze the time complexity of the following Min Stack implementation.

type MinStack struct {
    stack    []int
    minStack []int
}

func (ms *MinStack) Push(val int) {
    ms.stack = append(ms.stack, val)
    if len(ms.minStack) == 0 || val <= ms.minStack[len(ms.minStack)-1] {
        ms.minStack = append(ms.minStack, val)
    }
}

func (ms *MinStack) Pop() {
    if len(ms.stack) == 0 {
        return
    }
    top := ms.stack[len(ms.stack)-1]
    ms.stack = ms.stack[:len(ms.stack)-1]
    if top == ms.minStack[len(ms.minStack)-1] {
        ms.minStack = ms.minStack[:len(ms.minStack)-1]
    }
}

func (ms *MinStack) GetMin() int {
    if len(ms.minStack) == 0 {
        return -1 // or error
    }
    return ms.minStack[len(ms.minStack)-1]
}

This code keeps two stacks: one for all values and one for current minimums.

Identify Repeating Operations

Look at the main operations and how often they repeat.

  • Primary operation: Push and Pop each add or remove one element from stacks.
  • How many times: Each operation works on the top element only, no loops inside.
How Execution Grows With Input

Each push or pop does a fixed number of steps regardless of stack size.

Input Size (n)Approx. Operations
10About 1 step per push/pop
100About 1 step per push/pop
1000About 1 step per push/pop

Pattern observation: The time per operation stays the same no matter how big the stack is.

Final Time Complexity

Time Complexity: O(1)

This means each push, pop, or get minimum takes the same short time no matter how many items are in the stack.

Common Mistake

[X] Wrong: "Finding the minimum must check all elements, so it takes longer as stack grows."

[OK] Correct: The min stack keeps track of minimums as we go, so getting the minimum is always quick without scanning all elements.

Interview Connect

Understanding how to keep track of extra information efficiently is a great skill. It shows you can design smart data structures that keep operations fast.

Self-Check

"What if we stored minimums only when they change, instead of every push? How would that affect time complexity?"

Practice

(1/5)
1. What is the main purpose of a Min Stack data structure?
easy
A. To retrieve the minimum element in constant time
B. To sort elements in ascending order
C. To store elements in a queue fashion
D. To reverse the order of elements

Solution

  1. Step 1: Understand Min Stack functionality

    A Min Stack is designed to keep track of the minimum element efficiently.
  2. Step 2: Identify the key feature

    It allows retrieving the minimum element in constant time, unlike a normal stack.
  3. Final Answer:

    To retrieve the minimum element in constant time -> Option A
  4. Quick Check:

    Min Stack = Fast minimum retrieval [OK]
Hint: Min Stack always tracks minimum for O(1) retrieval [OK]
Common Mistakes:
  • Thinking it sorts elements
  • Confusing with queue behavior
  • Assuming it reverses elements
2. Which of the following Go code snippets correctly declares a Min Stack struct with two slices for values and minimums?
easy
A. type MinStack struct { values map[int]int; mins []int }
B. type MinStack struct { values []int; min int }
C. type MinStack struct { values []int; mins []int }
D. type MinStack struct { values []int; mins int }

Solution

  1. Step 1: Check struct fields for Min Stack

    Min Stack needs slices to store all values and track minimums at each push.
  2. Step 2: Validate field types

    Both values and mins should be slices of int for stack behavior.
  3. Final Answer:

    type MinStack struct { values []int; mins []int } -> Option C
  4. Quick Check:

    Two int slices = correct Min Stack struct [OK]
Hint: Min Stack uses two int slices for values and mins [OK]
Common Mistakes:
  • Using map instead of slice for values
  • Using int instead of slice for mins
  • Mixing types between fields
3. Given the following Go code for a Min Stack, what will be printed after the operations?
ms := MinStack{}
ms.Push(3)
ms.Push(5)
ms.Push(2)
ms.Push(1)
ms.Pop()
fmt.Println(ms.GetMin())
medium
A. 2
B. 1
C. 3
D. 5

Solution

  1. Step 1: Trace Push operations and minimums

    Push 3 (min=3), Push 5 (min=3), Push 2 (min=2), Push 1 (min=1).
  2. Step 2: Pop removes last pushed (1), so min updates to previous min (2)

    After pop, minimum is 2.
  3. Final Answer:

    2 -> Option A
  4. Quick Check:

    Pop last min 1, new min = 2 [OK]
Hint: Pop removes last min, so min updates to previous min [OK]
Common Mistakes:
  • Assuming min stays 1 after pop
  • Confusing push order
  • Not updating min stack on pop
4. Identify the bug in this Go Min Stack Pop method:
func (ms *MinStack) Pop() {
  ms.values = ms.values[:len(ms.values)-1]
  ms.mins = ms.mins[:len(ms.mins)]
}
medium
A. Pop method should return the popped value
B. The values slice is not shortened on pop
C. Pop method should clear both slices completely
D. The mins slice is not shortened on pop

Solution

  1. Step 1: Analyze slice operations in Pop

    Values slice is shortened by one element correctly.
  2. Step 2: Check mins slice operation

    Mins slice is sliced to full length, so it is not shortened, causing mismatch.
  3. Final Answer:

    The mins slice is not shortened on pop -> Option D
  4. Quick Check:

    mins slice must shrink with values [OK]
Hint: Pop must shrink both values and mins slices equally [OK]
Common Mistakes:
  • Forgetting to shrink mins slice
  • Assuming Pop returns value
  • Clearing slices fully on pop
5. You want to design a Min Stack that supports Push, Pop, Top, and GetMin all in O(1) time. Which approach below correctly handles the minimum tracking when pushing a new element x?
hard
A. Push x to values; push x only if x < current min to mins
B. Push x to values; push min(x, current min) to mins
C. Push x to values; push current min only if x > current min to mins
D. Push x to values; do not update mins slice

Solution

  1. Step 1: Understand min tracking logic

    Each push must record the minimum so far to allow O(1) GetMin.
  2. Step 2: Compare new element with current min

    Push the smaller of x and current min onto mins slice to keep track.
  3. Final Answer:

    Push x to values; push min(x, current min) to mins -> Option B
  4. Quick Check:

    Always push min(x, current min) to mins [OK]
Hint: Always push min of new and current min to mins stack [OK]
Common Mistakes:
  • Pushing x only if smaller causes missing mins
  • Not updating mins on every push
  • Ignoring mins slice updates
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard