2034. 股票价格波动

股票价格数据流设计与实现详解 —— StockPrice 类的设计与优化

题目描述

给你一个股票价格的数据流,数据流中每条记录包含一个时间戳和该时间点对应的股票价格。由于市场波动,数据流中:

  • 记录可能不是按时间顺序到来的
  • 某些时间戳的价格记录可能是错误的,若后续出现同一时间戳的记录,则新的记录更正之前的错误

请设计一个 StockPrice 类,实现以下功能:

  • 更新某时间戳的股票价格(若该时间戳已有价格则更正);
  • 查询当前最新时间戳的股票价格;
  • 查询当前所有记录中的最高股票价格;
  • 查询当前所有记录中的最低股票价格。

API 设计:

class StockPrice:
    def __init__(self):
        # 初始化,当前无股票价格记录

    def update(self, timestamp: int, price: int) -> None:
        # 在时间点 timestamp 更新股票价格为 price

    def current(self) -> int:
        # 返回当前最新时间戳对应的股票价格

    def maximum(self) -> int:
        # 返回当前所有股票价格的最高价

    def minimum(self) -> int:
        # 返回当前所有股票价格的最低价

示例说明

输入:

["StockPrice", "update", "update", "current", "maximum", "update", "maximum", "update", "minimum"]
[[], [1, 10], [2, 5], [], [], [1, 3], [], [4, 2], []]

执行过程及输出:

stockPrice = StockPrice()
stockPrice.update(1, 10)     # 时间戳为1,价格10
stockPrice.update(2, 5)      # 时间戳为2,价格5
print(stockPrice.current())  # 最新时间戳为2,价格为5
print(stockPrice.maximum())  # 最高价格为10
stockPrice.update(1, 3)      # 更正时间戳1的价格为3
print(stockPrice.maximum())  # 最高价格变为5(因为时间戳1价格从10变3)
stockPrice.update(4, 2)      # 时间戳4价格2
print(stockPrice.minimum())  # 最低价格为2

输出:

5
10
5
2

解题分析

1. 需求分析

  • 需要按时间戳快速更新价格,且支持价格覆盖(更正)。
  • 需要快速找到当前最新时间戳对应的价格。
  • 需要快速查询最高价最低价
  • 价格更新时,要能正确更新最高价和最低价(支持多次更新同一时间戳的价格)。
  • 最高价和最低价查询操作需要高效。

2. 关键点

  • 记录数据可能乱序到达。
  • 旧价格可能被更正(相同时间戳后续更新),因此最高/最低价堆中旧的价格会失效,需要能“跳过”。
  • 需要快速访问最新时间戳。

解题方法

核心数据结构设计

  1. 哈希表 **timestamp_price_map**
    • 维护时间戳到当前最新价格的映射。
    • 支持快速更新和查询。
  2. 最大堆 **max_heap** 和最小堆 **min_heap**
    • max_heap 存储元素为 (-price, timestamp),方便快速获取最大价格。
    • min_heap 存储元素为 (price, timestamp),方便快速获取最小价格。
    • 堆中可能存在旧的过期记录,需要在查询时惰性删除(跳过失效项)。
  3. 变量 **latest_timestamp**
    • 记录当前数据中最大时间戳,方便 current() 查询。

具体操作实现

update(timestamp, price)
  • timestamp_price_map[timestamp] = price 更新或新增。
  • 更新 latest_timestamp = max(latest_timestamp, timestamp)
  • 将新 (price, timestamp) 推入 max_heapmin_heap

注意:旧的堆中元素并不立即删除,等待查询时惰性删除。

current()
  • 直接返回 timestamp_price_map[latest_timestamp]
maximum()
  • 不断检查 max_heap 堆顶元素 (neg_price, timestamp) 是否仍有效(即 timestamp_price_map[timestamp] == -neg_price)。
  • 如果无效则弹出,直到找到有效最大值,返回它。
minimum()
  • 类似 maximum(),从 min_heap 取堆顶,判断有效性,弹出无效元素,返回有效最小值。

代码实现

import heapq

class StockPrice:
    def __init__(self):
        self.timestamp_price_map = {}
        self.max_heap = []  # (-price, timestamp)
        self.min_heap = []  # (price, timestamp)
        self.latest_timestamp = 0

    def update(self, timestamp: int, price: int) -> None:
        self.timestamp_price_map[timestamp] = price
        self.latest_timestamp = max(self.latest_timestamp, timestamp)
        heapq.heappush(self.max_heap, (-price, timestamp))
        heapq.heappush(self.min_heap, (price, timestamp))

    def current(self) -> int:
        return self.timestamp_price_map[self.latest_timestamp]

    def maximum(self) -> int:
        while True:
            neg_price, timestamp = self.max_heap[0]
            if self.timestamp_price_map[timestamp] == -neg_price:
                return -neg_price
            heapq.heappop(self.max_heap)

    def minimum(self) -> int:
        while True:
            price, timestamp = self.min_heap[0]
            if self.timestamp_price_map[timestamp] == price:
                return price
            heapq.heappop(self.min_heap)

复杂度分析

操作时间复杂度备注
updateO(log N)插入堆元素
currentO(1)直接哈希表查找
maximum摊还 O(log N)可能弹出过期堆元素
minimum摊还 O(log N)同上

空间复杂度为 O(N),N 是更新的总次数。


方法比较

方案优点缺点
维护哈希表 + 最大/最小堆查询高效,支持乱序更新,惰性删除简单堆空间可能大,需惰性清理
线性扫描(简单数组)实现简单查询慢,O(N) 不适合大量数据
平衡树(红黑树/AVL等)有序数据结构,查询快复杂度较高,语言支持限制

结语

这道题考察了数据结构设计与更新机制,重点在于如何处理“旧数据失效”问题,利用惰性删除实现高效维护最大/最小值,同时通过哈希表快速更新同时间戳的价格。

代码简洁、性能优秀,适合面试和实际系统的设计需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值