题目:
编写一个 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%。
思路:
单调栈
调用next 时,输入是新的一天的股票价格,需要返回包含此日在内的,往前数最多有连续多少日的股票价格是小于等于今日股票价格的。如果把每日的price 当成数组不同下标的值,即需要求出每个值与上一个更大元素之间的下标之差。这种题目可以用单调栈求解。此题的具体解法上,栈的元素可以是股票价格的下标(即天数)和股票价格的二元数对,并且在栈中先插入一个最大值作为天数为 −1 天的价格,来保证栈不会为空。调用 next 时,先将栈中价格小于等于此时price 的元素都弹出,直到遇到一个大于price 的值,并将price 入栈,计算下标差返回
java代码:
class StockSpanner {
Deque<int[]> stack;
int idx;
public StockSpanner() {
stack = new ArrayDeque<int[]>();
stack.push(new int[]{-1, Integer.MAX_VALUE});
idx = -1;
}
public int next(int price) {
idx++;
while (price >= stack.peek()[1]) {
stack.pop();
}
int ret = idx - stack.peek()[0];
stack.push(new int[]{idx, price});
return ret;
}
}
网友评论