Stock Span Problem Using Stack in DSA C# - Time & Space Complexity
We want to understand how the time taken grows when we calculate stock spans for many days.
How does the number of operations change as the list of stock prices gets bigger?
Analyze the time complexity of the following code snippet.
public int[] CalculateSpan(int[] prices) {
int n = prices.Length;
int[] span = new int[n];
Stack<int> stack = new Stack<int>();
for (int i = 0; i < n; i++) {
while (stack.Count > 0 && prices[stack.Peek()] <= prices[i]) {
stack.Pop();
}
span[i] = (stack.Count == 0) ? (i + 1) : (i - stack.Peek());
stack.Push(i);
}
return span;
}
This code calculates the stock span for each day using a stack to track previous higher prices.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop runs once for each price (n times).
- Inside loop: The while-loop pops from the stack, but each element is pushed and popped at most once.
- Dominant operation: The combined push and pop operations over all iterations.
As the number of days (n) increases, the total operations grow roughly in a straight line.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 (each element pushed and popped once) |
| 100 | About 200 |
| 1000 | About 2000 |
Pattern observation: Operations increase roughly in direct proportion to input size.
Time Complexity: O(n)
This means the time to calculate spans grows linearly with the number of prices.
[X] Wrong: "The while-loop inside the for-loop makes this O(n²) because it can run many times each iteration."
[OK] Correct: Each price index is pushed and popped only once, so total while-loop operations across all iterations add up to n, not n².
Understanding this linear time solution shows you how to use stacks smartly to avoid repeated work, a skill valuable in many coding challenges.
"What if we used a simple nested loop without a stack? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem definition
The Stock Span Problem finds how many days before today had prices less than or equal to today's price consecutively.Step 2: Clarify what is calculated for each day
For each day, it counts consecutive previous days with prices not higher than the current day.Final Answer:
The number of consecutive days before the current day with a price less than or equal to the current day's price -> Option CQuick Check:
Stock span = consecutive days with price ⤠current day price [OK]
- Confusing span with maximum price
- Counting all previous days instead of consecutive
- Calculating price differences instead of counts
Solution
Step 1: Identify the correct data structure for stack
In C#, Stack<T> is the built-in class for stack operations.Step 2: Check each option's data structure
Stack<int> stack = new Stack<int>(); uses Stack<int>, which is correct. int[] stack = new int[10]; uses array, List<int> stack = new List<int>(); uses List, which are not stacks. Queue<int> stack = new Queue<int>(); uses Queue, which is FIFO, not LIFO.Final Answer:
Stack<int> stack = new Stack<int>(); -> Option AQuick Check:
Stack<T> is the correct stack type in C# [OK]
- Using List instead of Stack
- Using Queue which is FIFO, not stack
- Using fixed-size array without stack methods
int[] prices = {100, 80, 60, 70, 60, 75, 85};
int[] span = new int[prices.Length];
Stack<int> stack = new Stack<int>();
for (int i = 0; i < prices.Length; i++) {
while (stack.Count > 0 && prices[stack.Peek()] <= prices[i]) {
stack.Pop();
}
span[i] = (stack.Count == 0) ? (i + 1) : (i - stack.Peek());
stack.Push(i);
}
Console.WriteLine(string.Join(", ", span));Solution
Step 1: Trace the stack and span calculation for each price
Day 0: stack empty, span[0] = 1, push 0
Day 1: prices[0]=100 > 80, no pop, span[1] = 1 - 0 = 1, push 1
Day 2: prices[1]=80 > 60, no pop, span[2] = 2 - 1 = 1, push 2
Day 3: prices[2]=60 <= 70, pop 2; prices[1]=80 > 70, span[3] = 3 - 1 = 2, push 3
Day 4: prices[3]=70 > 60, no pop, span[4] = 4 - 3 = 1, push 4
Day 5: prices[4]=60 <= 75 pop 4; prices[3]=70 <= 75 pop 3; prices[1]=80 > 75 no pop, span[5] = 5 - 1 = 4, push 5
Day 6: prices[5]=75 <= 85 pop 5; prices[1]=80 <= 85 pop 1; prices[0]=100 > 85 no pop, span[6] = 6 - 0 = 6, push 6Step 2: Collect the span array
The span array is [1, 1, 1, 2, 1, 4, 6].Final Answer:
[1, 1, 1, 2, 1, 4, 6] -> Option AQuick Check:
Span matches consecutive days with price ⤠current day [OK]
- Not popping all smaller or equal prices
- Using wrong index difference for span
- Confusing span with price values
int[] prices = {10, 4, 5, 90, 120, 80};
int[] span = new int[prices.Length];
Stack<int> stack = new Stack<int>();
for (int i = 0; i < prices.Length; i++) {
while (stack.Count > 0 && prices[stack.Peek()] <= prices[i]) {
stack.Pop();
}
span[i] = (stack.Count == 0) ? i : (i - stack.Peek());
stack.Push(i);
}
Console.WriteLine(string.Join(", ", span));Solution
Step 1: Check the span calculation when stack is empty
When stack is empty, span should be i + 1 because all previous days are counted.Step 2: Identify the error in span assignment
Code uses span[i] = i instead of i + 1, which undercounts span for first element and others when stack is empty.Final Answer:
The span calculation should use i + 1 when stack is empty -> Option DQuick Check:
Empty stack span = i + 1, not i [OK]
- Using i instead of i+1 for empty stack span
- Storing prices in stack instead of indices
- Wrong comparison operator causing incorrect pops
Solution
Step 1: Understand the original comparison
The original algorithm pops indices while prices at stack top are less than or equal to current price.Step 2: Modify comparison for strictly less
To count only days with price strictly less, change <= to < in the while condition.Final Answer:
Change the comparison in the while loop from prices[stack.Peek()] <= prices[i] to prices[stack.Peek()] < prices[i] -> Option BQuick Check:
Use < instead of ⤠for strict less span [OK]
- Using >= instead of < causing wrong pops
- Switching to queue which breaks logic
- Ignoring price comparison and counting all days
Ready to prove it?
Pass the test and this pattern moves unknown
