一、题目
编写一个 StockSpanner 类,它收集某些股票的每日报价,并返回该股票当日价格的跨度。
今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天)。
例如,如果未来7天股票的价格是 [100, 80, 60, 70, 60, 75, 85],那么股票跨度将是 [1, 1, 1, 2, 1, 4, 6]。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/online-stock-span
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路
题目要求,求出传进来price的当日股票价格的跨度。这就要求出price以及之前小于等于price的天数。观察题目的例子:
以70为例,从70往左找,小于等于70的,只有他自身和60,所以返回当日价格跨度2。从给定数据观察发现,往左边找到大于price的第一个数就停止。但是如果遍历左边所有的元素来判断是否大于当前值,如果元素过多,不断遍历判断就会非常麻烦。再次观察,我们发现,如果不保存price左边小于price的数字,就能够简化操作,例如70的时候,左边小于70的60就不用保存。计算的时候就可以把70对应的当日价格跨度加上。(因为price大于左边的一个大数,必然大于其中的小数。如果比大数小,则必然不连续)。
由于需要不断需要在后边增添和删除,我们选择栈来存储数据。
三、代码
// 此代码为LeetCode官方题解
import java.util.Stack;
public class StockSpanner {
private Stack<Integer> prices; // 股票价格
private Stack<Integer> stockSpans; // 股票跨度
public StockSpanner() {
prices = new Stack<Integer>();
stockSpans = new Stack<Integer>();
}
public int next(int price) {
// 自身跨度为1
int stockSpan = 1;
// 不断查看前面有几天小于等于price
while (!prices.empty() && prices.peek() <= price) {
// 从栈中舍弃掉该数字
prices.pop();
// 跨度累加计算
stockSpan += stockSpans.pop();
}
prices.push(price);
stockSpans.push(stockSpan);
return stockSpan;
}
}