Design an algorithm that collects daily price quotes for some stock and returns the span of that stock's price for the current day.
The span of the stock's price in one day is the maximum number of consecutive days (starting from that day and going backward) for which the stock price was less than or equal to the price of that day.
[7,2,1,2]
and the price of the stock today is 2
, then the span of today is 4
because starting from today, the price of the stock was less than or equal 2
for 4
consecutive days.[7,34,1,2]
and the price of the stock today is 8
, then the span of today is 3
because starting from today, the price of the stock was less than or equal 8
for 3
consecutive days.Implement the StockSpanner
class:
StockSpanner()
Initializes the object of the class.int next(int price)
Returns the span of the stock's price given that today's price is price
.Example 1:
Input ["StockSpanner", "next", "next", "next", "next", "next", "next", "next"] [[], [100], [80], [60], [70], [60], [75], [85]] Output [null, 1, 1, 1, 2, 1, 4, 6] Explanation StockSpanner stockSpanner = new StockSpanner(); stockSpanner.next(100); // return 1 stockSpanner.next(80); // return 1 stockSpanner.next(60); // return 1 stockSpanner.next(70); // return 2 stockSpanner.next(60); // return 1 stockSpanner.next(75); // return 4, because the last 4 prices (including today's price of 75) were less than or equal to today's price. stockSpanner.next(85); // return 6
Constraints:
1 <= price <= 105
104
calls will be made to next
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for the online stock span problem involves, for each new stock price, looking back at all the previous prices. We want to find the number of consecutive days before and including the current day where the stock price was less than or equal to the current day's price.
Here's how the algorithm would work step-by-step:
class StockSpanner:
def __init__(self):
self.stock_prices = []
def next(self, price):
span = 1
current_index = len(self.stock_prices)
self.stock_prices.append(price)
# Iterate backwards to find consecutive smaller prices
for previous_index in range(current_index - 1, -1, -1):
# Compare current price with previous prices
if self.stock_prices[previous_index] <= price:
span += 1
else:
# Stop when a larger price is found
break
return span
The key idea is to keep track of the relevant prices we've seen so far using a special tool. This tool helps us quickly find the most recent price that's bigger than the current price, so we can count how many consecutive days have a price less than or equal to the current day's price.
Here's how the algorithm would work step-by-step:
class StockSpanner:
def __init__(self):
self.price_and_span_stack = []
def next(self, price):
span = 1
# Pop prices from stack smaller or equal than current price
while self.price_and_span_stack and self.price_and_span_stack[-1][0] <= price:
span += self.price_and_span_stack[-1][1]
self.price_and_span_stack.pop()
# The current price and its span are added to the stack.
self.price_and_span_stack.append((price, span))
return span
# Your StockSpanner object will be instantiated and called as such:
# stock_spanner = StockSpanner()
# result1 = stock_spanner.next(price1)
# result2 = stock_spanner.next(price2)
# result3 = stock_spanner.next(price3)
Case | How to Handle |
---|---|
Empty input stream of stock prices | Initialize the data structure and return 0 for the first span query, or throw an exception depending on desired behavior. |
Monotonically increasing stock prices | The stack will grow linearly, storing all previous prices, leading to a span equal to the current index plus one. |
Monotonically decreasing stock prices | The span will always be 1 since no previous stock is less than or equal to the current price. |
Large input stream causing stack overflow (memory limits) | The stack size should be monitored and potentially optimized using alternative data structures if memory becomes a constraint. |
Integer overflow in stack operations or span calculation. | Use a data type with a larger range (e.g., long) for the stack and span calculations to prevent potential overflows. |
Prices with large fluctuations | The stack will fluctuate in size as larger prices clear smaller prices, resulting in a mixed performance profile. |
Zero or negative stock prices | The algorithm should work correctly as comparisons are based on relative price and the span is computed regardless of the specific price values as long as we can perform mathematical comparisons. |
Prices at the maximum integer value for the given language | Carefully compare integers to prevent the stack and algorithm to work without integer overflow related issues. |