红黑树的介绍看这篇博文,看的时候第一遍看,第二遍画

2034. 股票价格波动

这一题的求解逻辑是这样,我们使用一个HashMap存储<timestamp, price>,再使用一个TreeMap存储<price, count>其中count是该价格出现的次数,即需要解决一个情况:在不同的时间可能出现相同的价格。
使用红黑树(java)/B树(Rust)都是利用二叉查找树的有序特性,在O(logn)时间查找值
那么我们在更新的时候就是三种情况,对于新来的<timestamp, price>

  1. 时间戳之前没有出现过,就直接插入
  2. 如果出现过,那么就更新HashMap为新的值,但是TreeMap注意了!!!
    1. 如果该price只出现过一次,那么就直接更新即可
    2. 如果曾经出现过几次,那么我们得保证被删除的时间戳的数量正确 ```rust /// 红黑树的应用题,2034. 股票价格波动 struct StockPrice { current: i32, data: std::collections::HashMap, // 正常来说需要使用红黑数,但是Rust底层实现是B树, // 不过不影响,都是二叉搜索树进化来的 with_time: std::collections::BTreeMap }

/**

  • &self means the method takes an immutable reference.
  • If you need a mutable reference, change it to &mut self instead. */ impl StockPrice {

    fn new() -> Self {

    1. Self {
    2. current: 0,
    3. data: Default::default(),
    4. with_time: Default::default()
    5. }

    }

    fn update(&mut self, timestamp: i32, price: i32) {

     // 必须存储的是最新的时间对应的价格
     self.current = self.current.max(timestamp);
     // 如果这个时间下有原始值,将那个值返回出来
     if let Some(old)  = self.data.insert(timestamp, price) {
         // 很方便的操作,获取到键值对old的,如果没有的话插入<old, 0>,返回value(这个0)的mut引用
         *self.with_time.entry(old).or_insert(0) -= 1;
         if self.with_time[&old] <= 0 {
             self.with_time.remove(&old);
         }
     }
     *self.with_time.entry(price).or_insert(0) +=1;
    

    }

    fn current(&self) -> i32 { // get返回的值是引用!!!!
    // self.data[&self.current] 能够直接返回内部的值,估计是拷贝出来一份 self.data.get(&self.current).expect(“数据错误!!!”).clone() }

    fn maximum(&self) -> i32 { // 和下面的拷贝是等价的,不会导致数据丢失 *self.with_time.iter().rev().next().expect(“数据为空!!!”).0 }

    fn minimum(&self) -> i32 { self.with_time.iter().next().expect(“数据为空!!!”).0.clone() } } ```