题目描述
设计一个算法收集某些股票的每日报价,并返回该股票当日价格的 跨度 。
当日股票价格的 跨度 被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天)。
-
例如,如果未来 7 天股票的价格是
[100,80,60,70,60,75,85]
,那么股票跨度将是[1,1,1,2,1,4,6]
。
实现 StockSpanner
类:
StockSpanner()
初始化类对象。int next(int price)
给出今天的股价price
,返回该股票当日价格的 跨度 。
示例:
输入: ["StockSpanner", "next", "next", "next", "next", "next", "next", "next"] [[], [100], [80], [60], [70], [60], [75], [85]] 输出: [null, 1, 1, 1, 2, 1, 4, 6] 解释: StockSpanner stockSpanner = new StockSpanner(); stockSpanner.next(100); // 返回 1 stockSpanner.next(80); // 返回 1 stockSpanner.next(60); // 返回 1 stockSpanner.next(70); // 返回 2 stockSpanner.next(60); // 返回 1 stockSpanner.next(75); // 返回 4 ,因为截至今天的最后 4 个股价 (包括今天的股价 75) 都小于或等于今天的股价。 stockSpanner.next(85); // 返回 6
提示:
1 <= price <= 105
- 最多调用
next
方法104
次
代码实现
class StockSpanner {
int i = 0;
stack<pair<int, int>> stk;
public:
StockSpanner() {
stk.push({0, INT_MAX});
}
int next(int price) {
i++;
while (price >= stk.top().second) {
stk.pop();
}
int ans = i - stk.top().first;
stk.push({i, price});
return ans;
}
};
/**
* Your StockSpanner object will be instantiated and called as such:
* StockSpanner* obj = new StockSpanner();
* int param_1 = obj->next(price);
*/
类定义
类 StockSpanner
有两个主要成员:
-
成员变量:
i
:一个整数,用于记录next
函数被调用的次数,相当于日子的索引。stk
:一个栈,用于存储价格和对应的索引。栈中的元素是一个pair<int, int>
,其中第一个元素是索引(天数),第二个元素是当天的价格。
-
构造函数:
- 构造函数中初始化栈,并且压入一个元素
{0, INT_MAX}
。这个元素是一个哨兵元素,确保在所有的价格处理完之前,栈中始终至少有一个元素,且这个元素的价格是最大的,这样在处理价格时始终能找到一个“天数”。
- 构造函数中初始化栈,并且压入一个元素
方法定义
next(int price)
:- 这个方法接收一个整数
price
,表示当前天的股票价格。 - 方法首先将索引
i
自增。 - 然后,它在栈不为空且栈顶的价格小于等于当前价格时,持续弹出栈顶元素。这个循环结束时,栈顶的元素将是第一个价格大于当前价格的日子的前一天。
- 计算
ans
,即当前天数i
与栈顶元素的天数的差,这表示从当前天数往前数,连续的天数中股票价格小于或等于当前价格的天数。 - 将当前天的索引和价格作为一对压入栈中。
- 返回计算出的
ans
。
- 这个方法接收一个整数
总结
StockSpanner
类的核心功能是通过使用栈来有效追踪和计算价格跨度。栈用于维护一个价格递减的序列,并且可以通过比较栈顶价格与当前价格快速确定当前价格的跨度。这个类利用栈的后进先出(LIFO)特性来回溯之前的价格,并找到合适的价格跨度。
这个类的实现是一个经典的栈应用案例,展示了如何使用栈解决实际问题,具体是在金融分析或股市数据处理中的应用。它不仅处理数据的存取效率高,而且代码逻辑清晰,易于理解和维护。