Leetcode:901. 股票价格跨度(栈)

本文介绍了一种使用单调栈解决股票价格跨度问题的算法。通过维护两个同步栈,分别记录股票价格和对应的连续日数,实现了高效计算股票价格跨度的功能。示例展示了如何通过StockSpanner类计算一系列股票价格的跨度。

901. 股票价格跨度

编写一个 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%。

这道题其实还是一个单调栈,这题为难我了,少看了一个关键信息,连续日,实在无语,想了很长时间也总觉得单调栈是不对的,甚至自己也设计了测试用例来验证自己的想法还正确了,哈哈,果然做题首先还是要细心读题啊,小学高中做了那么多的题连基础都给忘了呀


这道题需要一个同步的栈,来记录另一个栈中的连续时长,变化一致

class StockSpanner {
    Stack<Integer>prices,weights;

    public StockSpanner() {
        prices=new Stack<Integer>();
        weights=new Stack<Integer>();

    }
    
    public int next(int price) {
        int w=1;
        while(!prices.isEmpty()&&price>=prices.peek()){
            prices.pop();
            w+=weights.pop();
        }
        weights.push(w);
        prices.push(price);
        return w;


    }
}

/**
 * Your StockSpanner object will be instantiated and called as such:
 * StockSpanner obj = new StockSpanner();
 * int param_1 = obj.next(price);
 */
### 单调算法概述 单调是一种特殊的数据结构,其核心在于通过维护一个具有单调性质(递增或递减)的来优化某些特定问题的解决方案。这种技术可以显著降低时间复杂度至 \( O(n) \)[^5]。 #### 基本原理 当处理数组中的元素时,如果当前元素破坏了内的单调性,则会弹出顶直到恢复单调性为止[^4]。这一特性使得单调非常适合用于寻找某个位置左侧或右侧第一个大于或小于它的值的问题。 --- ### 应用场景 1. **柱状图最大矩形面积** 给定一组高度不等的直方条,目标是找出这些直方条所能围成的最大矩形区域大小。此问题是单调的经典应用之一[^2]。 2. **股票价格跨度计算** 对于每日股价记录,需快速查询某一天之前连续多少天的价格均低于当天价格。利用单调递减可高效完成此类任务。 3. **最近较小/较大值查找** 需要确定每个元素左右两侧距离最近且满足条件(更小或者更大)的位置索引情况,在图像处理等领域有广泛用途。 --- ### 实现方式 以下是基于 Python 的具体实现案例: #### 求解柱状图中最大的矩形面积 ```python def largestRectangleArea(heights): stack = [] # 使用列表模拟操作 heights.append(0) # 添加哨兵节点简化边界判断逻辑 max_area = 0 i = 0 while i < len(heights): if not stack or heights[i] >= heights[stack[-1]]: stack.append(i) i += 1 else: top_index = stack.pop() width = i if not stack else (i - stack[-1] - 1) area = heights[top_index] * width max_area = max(max_area, area) return max_area ``` 上述代码片段展示了如何运用单调解决柱状图最大矩形面积问题。其中关键是借助辅助变量 `width` 来动态调整宽度范围并更新全局最优解。 #### 构建单调递减示例 考虑输入序列为 `[9,2,7,1,6,4,3,5]` ,下面演示创建一个单调递减的过程[^3]: ```python nums = [9, 2, 7, 1, 6, 4, 3, 5] decreasing_stack = [] result = [] for num in nums: while decreasing_stack and num > decreasing_stack[-1]: result.append(decreasing_stack.pop()) decreasing_stack.append(num) while decreasing_stack: result.append(decreasing_stack.pop()) print(result) # 输出最终结果顺序反映原序列经过单向筛选后的形态特征 ``` 这里我们遍历整个数组,并按照既定规则不断调整内部状态直至结束循环得到预期输出形式。 --- ### 总结说明 通过对以上理论阐述以及实际编码演练可以看出,掌握好单调技巧不仅有助于提升程序运行效率还能增强解决问题的能力水平。希望读者能够深入理解背后蕴含的思想精髓从而灵活应用于更多场合之中!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值