红黑树的介绍看这篇博文,看的时候第一遍看,第二遍画
2034. 股票价格波动
这一题的求解逻辑是这样,我们使用一个HashMap存储<timestamp, price>,再使用一个TreeMap存储<price, count>其中count是该价格出现的次数,即需要解决一个情况:在不同的时间可能出现相同的价格。
使用红黑树(java)/B树(Rust)都是利用二叉查找树的有序特性,在O(logn)时间查找值
那么我们在更新的时候就是三种情况,对于新来的<timestamp, price>
- 时间戳之前没有出现过,就直接插入
- 如果出现过,那么就更新HashMap为新的值,但是TreeMap注意了!!!
- 如果该price只出现过一次,那么就直接更新即可
- 如果曾经出现过几次,那么我们得保证被删除的时间戳的数量正确
```rust
/// 红黑树的应用题,2034. 股票价格波动
struct StockPrice {
current: i32,
data: std::collections::HashMap
, // 正常来说需要使用红黑数,但是Rust底层实现是B树, // 不过不影响,都是二叉搜索树进化来的 with_time: std::collections::BTreeMap }
/**
&selfmeans the method takes an immutable reference.If you need a mutable reference, change it to
&mut selfinstead. */ impl StockPrice {fn new() -> Self {
Self {current: 0,data: Default::default(),with_time: Default::default()}
}
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() } } ```
