问题描述
小C是一名股票交易员,最近他关注某只股票的价格波动。给定该股票连续N天的价格列表 stockPrices,你需要为小C生成一个新列表,每个位置的值表示从那天起至少需要等待多少天才能看到价格上涨。如果没有上涨的情况,则对应位置的值为0。
例如,对于股票价格列表 [33, 34, 14, 12, 16],从第一天价格 33 开始,价格上涨发生在第二天价格 34,所以输出 1。若某天之后不再有价格上涨,则输出 0。
当然,我会对您的代码进行详细解释。
代码解释
def solution(N: int, stockPrices: list) -> list:
# 初始化结果列表
result = [0] * N
# 使用栈来存储价格的下标
stack = []
# 遍历价格列表
for i in range(N):
# 当栈不为空且栈顶元素对应的价格小于当前价格时
while stack and stockPrices[stack[-1]] < stockPrices[i]:
# 计算栈顶元素与当前元素的距离,并更新结果列表
prev_index = stack.pop()
result[prev_index] = i - prev_index
# 将当前元素的下标入栈
stack.append(i)
return result
if __name__ == '__main__':
print(solution(5, [33, 34, 14, 12, 16]) == [1, 0, 2, 1, 0])
print(solution(6, [45, 44, 46, 43, 42, 48]) == [2, 1, 3, 2, 1, 0])
print(solution(3, [10, 9, 8]) == [0, 0, 0])
详细解释
-
函数定义:
solution(N: int, stockPrices: list) -> list: 这个函数接受两个参数:N表示股票价格的天数,stockPrices是一个包含N天股票价格的列表。函数返回一个列表,表示从每一天起至少需要等待多少天才能看到价格上涨。
-
初始化结果列表:
result = [0] * N: 初始化一个长度为N的列表,所有元素初始值为0。这个列表将存储最终的结果。
-
使用栈来存储价格的下标:
stack = []: 初始化一个空栈,用于存储股票价格的下标。栈的目的是帮助我们找到每个价格之后第一个比它高的价格。
-
遍历价格列表:
for i in range(N): 遍历每一天的股票价格。
-
栈的操作:
while stack and stockPrices[stack[-1]] < stockPrices[i]: 当栈不为空且栈顶元素对应的价格小于当前价格时,执行以下操作:prev_index = stack.pop(): 弹出栈顶元素,这个元素是之前存储的价格下标。result[prev_index] = i - prev_index: 计算当前价格下标与栈顶元素下标的差值,并将其存储在结果列表的相应位置。这个差值表示从prev_index天起需要等待多少天才能看到价格上涨。
-
将当前元素的下标入栈:
stack.append(i): 将当前价格的下标i压入栈中。
-
返回结果:
return result: 返回结果列表。
-
测试代码:
if __name__ == '__main__':: 这部分代码用于测试solution函数。它调用solution函数并打印结果,以验证函数的正确性。
知识点总结
1. 栈(Stack)
- 概念:栈是一种后进先出(LIFO, Last In First Out)的数据结构。栈的基本操作包括压入(push)和弹出(pop)。
- 应用:在您的代码中,栈用于存储股票价格的下标。通过栈,可以高效地找到每个价格之后第一个比它高的价格。
2. 列表(List)
- 概念:列表是Python中的一种基本数据结构,可以存储多个元素,并且支持动态调整大小。
- 应用:在您的代码中,
result列表用于存储最终的结果,stockPrices列表用于存储输入的股票价格。
3. 循环(Loop)
- 概念:循环是一种控制结构,用于重复执行一段代码。
- 应用:在您的代码中,
for i in range(N)循环用于遍历每一天的股票价格。
4. 条件判断(Conditional Statement)
- 概念:条件判断用于根据条件执行不同的代码块。
- 应用:在您的代码中,
while stack and stockPrices[stack[-1]] < stockPrices[i]用于判断栈是否为空以及栈顶元素对应的价格是否小于当前价格。
5. 函数定义与调用
- 概念:函数是一段可重用的代码块,用于执行特定的任务。函数可以接受参数并返回结果。
- 应用:在您的代码中,
solution函数接受两个参数并返回一个结果列表。if __name__ == '__main__':用于测试solution函数。
6. 列表操作
- 概念:列表操作包括访问、修改、添加和删除列表中的元素。
- 应用:在您的代码中,
result = [0] * N用于初始化结果列表,stack.append(i)用于将元素压入栈,stack.pop()用于弹出栈顶元素。
7. 时间复杂度与空间复杂度
- 概念:时间复杂度用于衡量算法执行时间随输入规模增长的变化趋势,空间复杂度用于衡量算法所需的额外空间。
- 应用:在您的代码中,使用栈的方法使得时间复杂度为
O(N),空间复杂度为O(N),非常适合处理这种问题。
8. 下标操作
- 概念:下标操作用于访问和修改列表中的特定元素。
- 应用:在您的代码中,
stockPrices[stack[-1]]用于访问栈顶元素对应的价格,result[prev_index] = i - prev_index用于更新结果列表中的特定位置。