Stock Span Problem Using Stack in DSA C++ - Time & Space Complexity
We want to understand how fast the stock span calculation runs when using a stack.
Specifically, how the number of operations grows as the number of stock prices increases.
Analyze the time complexity of the following code snippet.
#include <stack>
#include <vector>
std::vector<int> calculateSpan(const std::vector<int>& prices) {
std::stack<int> s;
std::vector<int> span(prices.size());
for (int i = 0; i < prices.size(); i++) {
while (!s.empty() && prices[s.top()] <= prices[i]) {
s.pop();
}
span[i] = s.empty() ? (i + 1) : (i - s.top());
s.push(i);
}
return span;
}
This code calculates the stock span for each day using a stack to track previous higher prices.
- Primary operation: The for-loop runs once for each price.
- Nested operation: The while-loop pops from the stack while the current price is higher.
- How many times: Each element is pushed and popped at most once, so total stack operations are linear.
As the number of prices grows, each price is processed once and stack operations happen at most once per price.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 operations (push and pop combined) |
| 100 | About 200 operations |
| 1000 | About 2000 operations |
Pattern observation: The operations grow roughly in a straight line with input size.
Time Complexity: O(n)
This means the time to calculate spans grows directly in proportion to the number of prices.
[X] Wrong: "The nested while-loop makes this algorithm O(n²) because it looks like a loop inside a loop."
[OK] Correct: Each price is pushed and popped only once, so the total number of while-loop operations across all iterations is at most n, keeping it linear.
Understanding this stack-based approach shows you how to use data structures smartly to improve efficiency, a skill valued 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 up to the current day had prices less than or equal to today's price consecutively.Step 2: Identify what the span represents
The span is the count of consecutive days including today where the price was not higher than today's price.Final Answer:
The number of consecutive days up to the current day with a price less than or equal to today's price -> Option DQuick Check:
Span counts consecutive days with price ⤠today [OK]
- Confusing span with maximum price
- Thinking span is difference of prices
- Assuming span is average price
Solution
Step 1: Identify the data structure needed for last-in-first-out access
The Stock Span Problem requires checking previous days' prices in reverse order, which suits a stack.Step 2: Choose the container that supports push/pop from one end efficiently
std::stack provides push and pop operations on the top element, perfect for this problem.Final Answer:
std::stack -> Option AQuick Check:
Stack supports LIFO needed for span calculation [OK]
- Using queue which is FIFO, not suitable
- Using vector without stack logic
- Using list which is less efficient here
[100, 80, 60, 70, 60, 75, 85] using the Stock Span algorithm?Solution
Step 1: Calculate span for each day
Day 1: 100 -> span=1
Day 2: 80 < 100 -> span=1
Day 3: 60 < 80 -> span=1
Day 4: 70 > 60 -> span=2 (includes day 3 and 4)
Day 5: 60 < 70 -> span=1
Day 6: 75 > 60, 70, 60 -> span=4 (days 3 to 6)
Day 7: 85 > 75, 70, 60, 80 -> span=6 (days 2 to 7)Step 2: Write the span array
The spans are [1, 1, 1, 2, 1, 4, 6].Final Answer:
[1, 1, 1, 2, 1, 4, 6] -> Option AQuick Check:
Span array matches calculated values [OK]
- Counting all previous days regardless of price
- Confusing span with cumulative sum
- Ignoring consecutive condition
std::stack<int> s;
int n = prices.size();
std::vector<int> span(n);
for (int i = 0; i < n; i++) {
while (!s.empty() && prices[s.top()] < prices[i]) {
s.pop();
}
span[i] = s.empty() ? i + 1 : i - s.top();
s.push(i);
}Solution
Step 1: Analyze the span calculation formula
The span for day i is the number of consecutive days including today with price less than or equal to today's price.Step 2: Check the formula used in code
The code uses span[i] = s.empty() ? i + 1 : i - s.top(); but this misses counting the current day properly.Step 3: Correct formula
The correct formula is span[i] = s.empty() ? i + 1 : i - s.top() + 1 to include the current day.Final Answer:
The span calculation should be i - s.top() + 1 instead of i - s.top() -> Option BQuick Check:
Adding +1 accounts for the current day in span [OK]
- Forgetting to add 1 in span calculation
- Storing prices instead of indices in stack
- Starting loop incorrectly at 1
[10, 4, 5, 90, 120, 80], how would the Stock Span algorithm change if we want to find the span of days with prices strictly less than today's price (not less than or equal)? What is the resulting span array?Solution
Step 1: Modify comparison to strictly less than
Change while condition to pop from stack while prices[s.top()] < prices[i], excluding equal prices.Step 2: Calculate spans with strict less than
Day 1: 10 -> span=1
Day 2: 4 < 10 -> span=1
Day 3: 5 > 4 -> span=2
Day 4: 90 > 5,4,10 -> span=4
Day 5: 120 > 90 -> span=5
Day 6: 80 < 120 -> span=1Final Answer:
[1, 1, 2, 4, 5, 1] -> Option CQuick Check:
Strict less than changes span for day 3 and 6 [OK]
- Not changing comparison operator correctly
- Miscounting spans for equal prices
- Assuming spans remain same as original problem
Ready to prove it?
Pass the test and this pattern moves unknown
