问题描述
小C是一名股票交易员,关注某只股票的价格波动。给定该股票连续N天的价格列表 stockPrices,需要生成一个新列表,每个位置的值表示从那天起至少需要等待多少天才能看到价格上涨。如果没有上涨的情况,则对应位置的值为0。
解题思路
- 单调栈:使用单调栈来解决这个问题。单调栈是一种栈,其中的元素保持单调递增或递减的顺序。
- 从后往前遍历:为了计算从当天起至少需要等待多少天才能看到价格上涨,从后往前遍历股票价格列表是一个高效的方法。
- 栈中存储索引:栈中存储的是未来日期的索引,而不是价格本身。这样可以方便地计算等待天数。
算法设计
-
初始化:
- 创建一个结果数组
result,长度为N,默认值为0。 - 创建一个空栈
stack,用于存储未来日期的索引。
- 创建一个结果数组
-
遍历股票价格:
-
从后往前遍历股票价格列表
stockPrices。 -
对于每个价格
stockPrices[i]:- 将栈中所有价格小于或等于当前价格
stockPrices[i]的索引弹出。 - 如果栈不为空,说明存在比当前价格高的未来日期,计算等待天数并更新
result[i]。 - 将当前日期索引
i压入栈。
- 将栈中所有价格小于或等于当前价格
-
-
返回结果:遍历结束后,返回结果数组
result。
代码分析
-
初始化结果数组和栈:
result = [0] * N stack = []这个部分初始化了一个长度为N的结果数组,默认值为0,以及一个空栈。
-
从后往前遍历:
for i in range(N - 1, -1, -1): while stack and stockPrices[i] >= stockPrices[stack[-1]]: stack.pop() if stack: result[i] = stack[-1] - i stack.append(i)这个部分从后往前遍历股票价格列表,使用栈来存储未来日期的索引,并根据栈中的索引计算等待天数。
有可能出现的问题
-
栈为空的处理:
- 当栈为空时,说明从当前日期起没有未来日期的价格比当前价格高,此时
result[i]应该保持为0。
- 当栈为空时,说明从当前日期起没有未来日期的价格比当前价格高,此时
-
边界条件处理:
- 最后一天的
result值一定是0,因为没有未来的日期可以比它更高。
- 最后一天的
-
栈中存储的索引顺序:
- 确保栈中存储的索引是单调递减的,这样可以在弹出操作时保证栈顶的索引对应的价格是未来比当前价格高的最近日期。
个人的思考与改进
-
优化栈的使用:
- 通过使用
collections.deque来替代普通的列表作为栈,可以更高效地进行弹出和压入操作。
- 通过使用
-
增加异常处理:
-
在实际应用中,可以增加异常处理来确保输入数据的有效性,例如检查
stockPrices是否为空或是否包含非数字元素。 -
例如,可以添加以下代码:
if not stockPrices or not all(isinstance(price, int) for price in stockPrices): raise ValueError("Invalid input: stockPrices must be a list of integers")
-
-
测试用例:
- 增加更多的测试用例,特别是边界条件和特殊情况,以确保代码的正确性和鲁棒性。
- 例如,测试空列表、价格全部相同的列表、价格逐渐下降的列表等。
-
代码可读性:
- 通过注释和合理的变量命名,提高代码的可读性和可维护性。例如,将
i命名为current_day,将stack[-1]命名为next_higher_day。
- 通过注释和合理的变量命名,提高代码的可读性和可维护性。例如,将