【力扣】哈希表+有序集合:2034. 股票价格波动

【力扣】哈希表+有序集合:2034. 股票价格波动

文章目录

  • 【力扣】哈希表+有序集合:2034. 股票价格波动
    • 1. 题目介绍
    • 2. 思路
    • 3. 解题代码
    • 4. Danger
    • 参考

1. 题目介绍

给你一支股票价格的数据流。数据流中每一条记录包含两个数据:

  • 一个 时间戳
  • 该时间戳股票对应的 价格

不巧的是,由于股票市场内在的波动性,股票价格记录可能不是按时间顺序到来的。某些情况下,有的记录可能是错的。如果两个有相同时间戳的记录出现在数据流中,前一条记录视为错误记录,后出现的记录 更正 前一条错误的记录。

1)请你设计一个算法,实现:

  • 更新 股票在某一时间戳的股票价格,如果有之前同一时间戳的价格,这一操作将 更正 之前的错误价格。
  • 找到当前记录里 最新股票价格 。最新股票价格 定义为时间戳最晚的股票价格。
  • 找到当前记录里股票的 最高价格 。
  • 找到当前记录里股票的 最低价格 。

2)代码实现 StockPrice 类:

  • StockPrice() 初始化对象,当前无股票价格记录。
  • void update(int timestamp, int price) 在时间点 timestamp 更新股票价格为 price 。
  • int current() 返回股票 最新价格 。
  • int maximum() 返回股票 最高价格 。
  • int minimum() 返回股票 最低价格 。

3)示例:
【力扣】哈希表+有序集合:2034. 股票价格波动_第1张图片

2. 思路

1)由于同一个时间戳可能出现多次,后面的记录会更正(覆盖)前面的记录,因此可以使用哈希表记录每个时间戳对应的股票价格。

  • 对于返回股票最新价格操作,我们可以维护最大的时间戳,用最大的时间戳在哈希表中查找,可以得到最新的股票价格。
  • 对于返回股票的最高和最低价格的操作,我们需要知道当前哈希表中的股票的最高和最低价格。我们可以使用有序集合维护哈希表中的股票价格,有序集合中的最大值和最小值即为当前哈希表中的股票的最高和最低价格。

因此,StockPrice 类需包含最大时间戳、哈希表和有序集合。初始化时,最大时间戳设为 0,哈希表和有序集合设为空。

  • 对于更新操作:
    • 从哈希表中得到时间戳 timestamp 对应的原价格,如果哈希表中没有时间戳 timestamp 对应的原价格,则将原价格记为 0(由于实际价格都大于 0,因此可以将原价格记为 0 表示哈希表中没有该时间戳);
    • 将哈希表中的时间戳 timestamp 对应的价格更新为新价格 price;
    • 如果原价格大于 0,即之前已经有时间戳 timestamp 对应的记录,则将原价格从有序集合中删除;
    • 在有序集合中加入新价格 prices。

注意,由于可能有重复的股票价格,对于不支持多重有序集合(如 C++ 中的 multiset)的语言,可以额外记录每个股票价格的出现次数,在加入、删除股票价格时,更新有序集合中该股票价格的出现次数。其余的操作可以直接从哈希表和有序集合中得到结果:

  • 对于返回股票最新价格操作,从哈希表中得到最大时间戳对应的股票价格并返回;
  • 对于返回股票最高价格操作,从有序集合中得到最大值,即为股票最高价格,将其返回;
  • 对于返回股票最低价格操作,从有序集合中得到最小值,即为股票最低价格,将其返回。

3. 解题代码

from sortedcontainers import SortedList

class StockPrice:
    def __init__(self):
        self.prices = SortedList()
        self.tpMap = {}
        self.maxTimestamp = 0

    def update(self, timestamp: int, prices: int) -> None:
        if timestamp in self.tpMap:
            self.prices.discard(self.tpMap[timestamp])	# 删除元素
        self.prices.add(prices)
        self.tpMap[timestamp] = prices
        self.maxTimestamp = max(self.maxTimestamp, timestamp)

    def current(self) -> int:
        return self.tpMap[self.maxTimestamp]

    def maximum(self) -> int:
        return self.prices[-1]

    def minimum(self) -> int:
        return self.prices[0]
  • 时间复杂度:

    • 初始化的时间复杂度是 O(1),
    • 更新操作、返回股票最高价格操作和返回股票最低价格操作的时间复杂度是 O(log⁡ n),
    • 返回股票最新价格操作的时间复杂度是 O(1),
    • 其中 n 是更新操作的次数。
    • 更新操作需要更新最大时间戳、哈希表和有序集合,
      • 更新最大时间戳和哈希表需要 O(1) 的时间,
      • 更新有序集合需要 O(log⁡ n) 的时间。
      • 返回股票最高价格操作和返回股票最低价格操作分别需要在有序集合中寻找最大值和最小值,需要 O(log⁡ n) 的时间。
    • 返回股票最新价格操作需要在哈希表中得到最大时间戳对应的股票价格,需要 O(1) 的时间。
  • 空间复杂度:O(n),其中 n 是更新操作的次数。空间复杂度主要取决于哈希表和有序集合,哈希表和有序集合中存储的元素个数不会超过更新操作的次数。

4. Danger

力扣(LeetCode)是领扣网络旗下专注于程序员技术成长和企业技术人才服务的品牌。源自美国硅谷,力扣为全球程序员提供了专业的IT技术职业化提升平台,有效帮助程序员实现快速进步和长期成长。此外,力扣(LeetCode)致力于解决程序员技术评估、培训、职业匹配的痛点,逐步引领互联网技术求职和招聘迈向专业化。

  • 据了解到的情况,Easy题和Medium 题在面试中比较常见,通常会以手写代码之类的形式出现,您需要对问题进行分析并给出解答,并于面试官进行交流沟通,有时还会被要求分析时间复杂度8与空间复杂度°,面试官会通过您对题目的分析解答,了解您对常用算法的熟悉程度和您的程序实现功底。
  • 而在一些对算法和程序实现功底要求较高的岗位,Hard 题也是很受到面试官的青睐,如果您在面试中成功Bug-Free出一道Hard题,我们相信您一定会给面试官留下很深刻的印象,并极大增加拿到Offer的概率,据相关人士统计,如果您在面试成功解出一道Hard题,拿不到Offer的概率无限接近于0。
  • 所以,力扣中Easy和Medium相当于面试中的常规题,而Hard 则相当于面试中较难的题,解出—道Hard题,Offer可以说是囊中之物。

参考

【1】https://leetcode.cn/problems/stock-prices-fluctuation

你可能感兴趣的:(#,力扣,编程题,leetcode,散列表,java)