文章目录
- Tag
- 题目来源
- 题目解读
- 解题思路
- 方法一:暴力枚举
- 方法二:单调栈
- 写在最后
Tag
【单调栈】【设计类】【数组】【2023-10-07】
题目来源
901. 股票价格跨度
题目解读
找出小于等于今天股票价格的最大连续天数(从今天往回数,包括今天)。
解题思路
方法一:暴力枚举
我们就按照题目中给出的关键信息从今天的股票开始往前找,找到小于等于当天股价的最大连续天数。由于股票的价格是通过 next
方法,调用一次给一次的,因此需要一个可变长数组来记录之前出现过的股票价格。
实现代码
class StockSpanner {
private:
vector<int> prices;
public:
StockSpanner() {
}
int next(int price) {
int n = prices.size();
int res = 1;
for (int i = n-1; i >= 0; --i) {
if (prices[i] <= price) {
++res;
}
else break;
}
prices.push_back(price);
return res;
}
};
/**
* Your StockSpanner object will be instantiated and called as such:
* StockSpanner* obj = new StockSpanner();
* int param_1 = obj->next(price);
*/
复杂度分析
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2),
n
n
n 为调用 next
方法的次数。因此本题中最多调用 next
方法
1
0
4
10^4
104 次,总的时间复杂度为
1
0
8
10^8
108,力扣对于这种数据规模还是可以通过的,数据规模要是达到了
1
0
9
10^9
109,那就不一定能通过了。
空间复杂度: O ( n ) O(n) O(n)。
方法二:单调栈
我们需要从当前股票价格开始往前查找连续小于等于当前价格的最大天数,也就是要求当前值与上一个更大的值的下标差。我们可以使用单调栈来解决。
具体地,我们维护一个栈 stk
,栈中存放的是表示第几天的股票 cur_day
以及价格 price
的数对 pair<int, int>
,我们初始化向栈底增加 (−1, ∞)
,这样栈就永远不会为空,并且可以方便判断等于的情况。
调用一次 next
方法:
++cur_day
,更新当前是第几天的股票,初始化为-1
;- 将
price
与栈顶的元素比较,如果比栈顶的股票价格大,就出栈,直到找到栈顶比price
大的那个元素,该元素就是我们要找的 “上一个更大的元素”; - 更新答案
res = cur_day - stk.pop().first
; - 将当前的股票天数与价格加入到栈中;
- 最后,返回答案
res
。
实现代码
class StockSpanner {
private:
stack<pair<int, int>> stk;
int cur_day = -1;
public:
StockSpanner() {
stk.push(make_pair(-1, INT_MAX));
cur_day = -1;
}
int next(int price) {
while (price >= stk.top().second) {
stk.pop();
}
++cur_day;
int res = cur_day - stk.top().first;
stk.push(make_pair(cur_day, price));
return res;
}
};
/**
* Your StockSpanner object will be instantiated and called as such:
* StockSpanner* obj = new StockSpanner();
* int param_1 = obj->next(price);
*/
复杂度分析
时间复杂度:
O
(
n
)
O(n)
O(n),
n
n
n 为调用 next
方法的次数,每个价格 price
最多都是入栈出栈 1
次。
空间复杂度: O ( n ) O(n) O(n)。
写在最后
如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。
最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。