力扣901(java&python)-股票价额跨度(中等)
题目:
编写一个 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%。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/online-stock-span
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
这是今天的每日一题,我不会做,害,看了题解区各位大佬的题解,这里记录一下~
单调栈:
题目的意思可以转换为,对于当日的价格,从这个价格开始往前查找,找到第一个比这个价格高的价格,这两个价格的下标差就是当日价格的跨度。
利用单调栈维护一个从栈底到栈顶单调递减的栈,栈中每个元素存放的是[price, count],price表示价格,count表示跨度。每次调用到next(price)时,就会比较当前price与栈顶的price,如果栈顶价格小于等于当前价格,则将栈顶的跨度加上当前价格的跨度,然后将栈顶元素出栈,直到栈顶价格大于当前价格或者栈为空。
图解来自@【Lemon】
java代码:
1 class StockSpanner { 2 Deque<int[]> stack = new ArrayDeque<>(); 3 4 public StockSpanner() { 5 6 } 7 8 public int next(int price) { 9 int count = 1; 10 while(!stack.isEmpty() && stack.peek()[0] <= price){ 11 count += stack.pop()[1]; 12 } 13 stack.push(new int[]{price, count}); 14 return count; 15 } 16 } 17 18 /** 19 * Your StockSpanner object will be instantiated and called as such: 20 * StockSpanner obj = new StockSpanner(); 21 * int param_1 = obj.next(price); 22 */
python3代码:
1 class StockSpanner: 2 3 def __init__(self): 4 self.stack = [] 5 6 def next(self, price: int) -> int: 7 count = 1 8 while self.stack and self.stack[-1][0] <= price: 9 count += self.stack.pop()[1] 10 self.stack.append((price, count)) 11 return count 12 13 14 # Your StockSpanner object will be instantiated and called as such: 15 # obj = StockSpanner() 16 # param_1 = obj.next(price)
小知识:
单调栈:存放的数据是有序的
- 单调递增栈:就是从栈底到栈顶数据是从大到小
- 单调递减栈:就是从栈底到栈顶数据是从小到大
单调栈的伪代码:
1 stack<int> st; 2 //此处一般需要给数组最后添加结束标志符 3 for (遍历这个数组) 4 { 5 if (栈空 || 栈顶元素大于等于当前比较元素) 6 { 7 入栈; 8 } 9 else 10 { 11 while (栈不为空 && 栈顶元素小于当前元素) 12 { 13 栈顶元素出栈; 14 更新结果; 15 } 16 当前数据入栈; 17 } 18 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理