持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情
编写一个 StockSpanner
类,它收集某些股票的每日报价,并返回该股票当日价格的跨度。
今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天)。
例如,如果未来7天股票的价格是 [100, 80, 60, 70, 60, 75, 85]
,那么股票跨度将是 [1, 1, 1, 2, 1, 4, 6]
。
示例:
输入: ["StockSpanner","next","next","next","next","next","next","next"], [[],[100],[80],[60],[70],[60],[75],[85]]
输出: [null,1,1,1,2,1,4,6]
解释:
首先,初始化 S = StockSpanner(),然后:
S.next(100) 被调用并返回 1,
S.next(80) 被调用并返回 1,
S.next(60) 被调用并返回 1,
S.next(70) 被调用并返回 2,
S.next(60) 被调用并返回 1,
S.next(75) 被调用并返回 4,
S.next(85) 被调用并返回 6。
注意 (例如) S.next(75) 返回 4,因为截至今天的最后 4 个价格
(包括今天的价格 75) 小于或等于今天的价格。
提示:
- 调用
StockSpanner.next(int price)
时,将有1 <= price <= 10^5
。 - 每个测试用例最多可以调用
10000
次StockSpanner.next
。 - 在所有测试用例中,最多调用
150000
次StockSpanner.next
。 - 此问题的总时间限制减少了 50%。
思路
本题可以使用单调栈求解。要求出小于等于今天价格的最大连续天数,需要找到最近大于今天价格的日子。可以维护一个价格的单调递减的栈。如果价格为[100, 80, 60, 70, 60, 75, 85]
,对应的栈为
[100]
[100, 80]
[100, 80, 60]
[100, 80, 70]
[100, 80, 70, 60]
[100, 80, 75]
[100, 85]
每次调用next的时候维护这个单调栈,然后计算栈末尾两个价格对应天数差即可。
解题
class StockSpanner {
constructor() {
this.list = [[1000000, 0]];
}
/**
* @param {number} price
* @return {number}
*/
next(price) {
let idx = this.list.length-1;
while (price >= this.list[idx][0]) {
idx = this.list[idx][1];
}
this.list.push([price, idx]);
return this.list.length - idx - 1;
}
}
/**
* Your StockSpanner object will be instantiated and called as such:
* var obj = new StockSpanner()
* var param_1 = obj.next(price)
*/