问题描述
小C是一名股票交易员,最近他关注某只股票的价格波动。给定该股票连续N天的价格列表 stockPrices,你需要为小C生成一个新列表,每个位置的值表示从那天起至少需要等待多少天才能看到价格上涨。如果没有上涨的情况,则对应位置的值为0。
例如,对于股票价格列表 [33, 34, 14, 12, 16],从第一天价格 33 开始,价格上涨发生在第二天价格 34,所以输出 1。若某天之后不再有价格上涨,则输出 0。
测试样例
样例1:
输入:
N = 5, stockPrices = [33, 34, 14, 12, 16]
输出:[1, 0, 2, 1, 0]
样例2:
输入:
N = 6, stockPrices = [45, 44, 46, 43, 42, 48]
输出:[2, 1, 3, 2, 1, 0]
样例3:
输入:
N = 3, stockPrices = [10, 9, 8]
输出:[0, 0, 0]
问题分析
我们可以将这个数组近似看作一座座山,而数组中的每个数就是山的高度。假设我们从右到左遍历,对于数组[33, 1,34, 14, 12, 16]来说,如果我们已经遍历过14,12,16这三个数,那么在后续的遍历中我们是无法看到12这个数的,因为对于14的出现,12绝不可能是1的下一个更大的数,而对于大于等于12的数就更不可能了。因此我们就可以放心地去掉12,再也不去遍历它了。
那我们就来模拟遍历一下,一开始遍历到16,记录一下,然后遍历到12,12比16小,我们就可以记录12,并且需要等待的天数标记为1.而对于14,14大于12,但14小于16,表示过了两天可以进行上涨。并且,小于14的这个12需要去掉,然后记录14.以此类推。
我们发现,记录的数据是加在最上面,去掉的数据也是最上面的,这种先进先出的特性我们可以使用栈来实现。并且,记录s[i]之前会把所有小于等于s[i]的数据丢掉,不可能出现上大下小,体现了单调性。
综上所示,我们可以使用单调栈来解决这个问题。
代码实现
- 时间复杂度:O(n)
- 空间复杂度:O(n)
本题总结
-
数据结构选择:
- 使用栈(stack)来辅助解决这个问题。栈可以帮助我们高效地找到下一个更大的元素。
-
算法步骤:
- 从后往前遍历
stockPrices列表。 - 对于每一天的价格,使用栈来记录后续的价格索引。
- 如果当前价格大于栈顶元素对应的价格,则弹出栈顶元素,直到找到一个更大的价格或者栈为空。
- 如果栈不为空,说明找到了下一个更大的价格,计算等待天数并记录。
- 如果栈为空,说明后续没有更大的价格,等待天数为0。
- 将当前索引入栈,继续遍历。
- 从后往前遍历
代码实现思路
-
初始化:
- 创建一个结果列表
ans,初始化为全0。 - 创建一个栈
st,用于存储价格索引。
- 创建一个结果列表
-
遍历:
- 从后往前遍历
stockPrices。 - 对于每一天的价格,使用栈来找到下一个更大的价格。
- 更新结果列表
ans。
- 从后往前遍历
-
返回结果:
- 返回结果列表
ans。
- 返回结果列表