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 <= 100,00010,000 calls will be made to next.Before attempting this problem, you should be comfortable with:
The stock span is the number of consecutive days (including today) where the price was less than or equal to today's price. The simplest approach is to store all prices and, for each new price, look backward through the history counting days until we find a higher price.
arr to store all prices seen so far.next(price) call:arr.arr[i] <= price.Where is the number of function calls.
The brute force approach repeatedly scans the same elements. We can avoid this by using a monotonic decreasing stack that stores pairs of (price, span).
When a new price arrives, we pop all entries from the stack that have prices less than or equal to the current price. The span of the current day is 1 (for today) plus the sum of spans of all popped entries. This works because those popped entries represent consecutive days that are now "covered" by the current higher price.
The stack remains in decreasing order of prices, so each element is pushed and popped at most once across all operations.
(price, span).next(price) call:span = 1 (counting today).(price, span) onto the stack.span.Where is the number of function calls.
The span includes all consecutive days where prices are less than or equal to the current price, not strictly less than. Using < instead of <= will undercount the span when previous days have the same price as today.
The span always includes the current day itself. When initializing the span counter, start with 1 (for today) before adding spans from popped elements. Starting with 0 will result in spans that are off by one.
Storing just prices on the stack requires recounting spans on every query, leading to O(n) per operation. The stack should store pairs of (price, span) so that when an element is popped, its accumulated span can be added directly to the current span in O(1) time.