Skip to content

Commit 621e81e

Browse files
committed
+ problem 2034
1 parent bb3dbcb commit 621e81e

File tree

5 files changed

+313
-0
lines changed

5 files changed

+313
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# 2034. Stock Price Fluctuation
2+
You are given a stream of **records** about a particular stock. Each record contains a **timestamp** and the corresponding **price** of the stock at that timestamp.
3+
4+
Unfortunately due to the volatile nature of the stock market, the records do not come in order. Even worse, some records may be incorrect. Another record with the same timestamp may appear later in the stream **correcting** the price of the previous wrong record.
5+
6+
Design an algorithm that:
7+
8+
* **Updates** the price of the stock at a particular timestamp, **correcting** the price from any previous records at the timestamp.
9+
* Finds the **latest price** of the stock based on the current records. The **latest price** is the price at the latest timestamp recorded.
10+
* Finds the **maximum price** the stock has been based on the current records.
11+
* Finds the **minimum price** the stock has been based on the current records.
12+
13+
Implement the `StockPrice` class:
14+
15+
* `StockPrice()` Initializes the object with no price records.
16+
* `void update(int timestamp, int price)` Updates the `price` of the stock at the given `timestamp`.
17+
* `int current()` Returns the **latest price** of the stock.
18+
* `int maximum()` Returns the **maximum price** of the stock.
19+
* `int minimum()` Returns the **minimum price** of the stock.
20+
21+
#### Example 1:
22+
<pre>
23+
<strong>Input:</strong>
24+
["StockPrice", "update", "update", "current", "maximum", "update", "maximum", "update", "minimum"]
25+
[[], [1, 10], [2, 5], [], [], [1, 3], [], [4, 2], []]
26+
<strong>Output:</strong>
27+
[null, null, null, 5, 10, null, 5, null, 2]
28+
<strong>Explanation:</strong>
29+
StockPrice stockPrice = new StockPrice();
30+
stockPrice.update(1, 10); // Timestamps are [1] with corresponding prices [10].
31+
stockPrice.update(2, 5); // Timestamps are [1,2] with corresponding prices [10,5].
32+
stockPrice.current(); // return 5, the latest timestamp is 2 with the price being 5.
33+
stockPrice.maximum(); // return 10, the maximum price is 10 at timestamp 1.
34+
stockPrice.update(1, 3); // The previous timestamp 1 had the wrong price, so it is updated to 3.
35+
// Timestamps are [1,2] with corresponding prices [3,5].
36+
stockPrice.maximum(); // return 5, the maximum price is 5 after the correction.
37+
stockPrice.update(4, 2); // Timestamps are [1,2,4] with corresponding prices [3,5,2].
38+
stockPrice.minimum(); // return 2, the minimum price is 2 at timestamp 4.
39+
</pre>
40+
41+
#### Constraints:
42+
* <code>1 <= timestamp, price <= 10<sup>9</sup></code>
43+
* At most <code>10<sup>5</sup></code> calls will be made **in total** to `update`, `current`, `maximum`, and `minimum`.
44+
* `current`, `maximum`, and `minimum` will be called **only after** `update` has been called **at least once**.
45+
46+
## Solutions (Rust)
47+
48+
### 1. Solution
49+
```Rust
50+
use std::cmp::Reverse;
51+
use std::collections::BinaryHeap;
52+
use std::collections::HashMap;
53+
54+
struct StockPrice {
55+
prices: HashMap<i32, i32>,
56+
max_time: i32,
57+
max_prices: BinaryHeap<(i32, i32)>,
58+
min_prices: BinaryHeap<(Reverse<i32>, i32)>,
59+
}
60+
61+
/**
62+
* `&self` means the method takes an immutable reference.
63+
* If you need a mutable reference, change it to `&mut self` instead.
64+
*/
65+
impl StockPrice {
66+
fn new() -> Self {
67+
Self {
68+
prices: HashMap::new(),
69+
max_time: 0,
70+
max_prices: BinaryHeap::new(),
71+
min_prices: BinaryHeap::new(),
72+
}
73+
}
74+
75+
fn update(&mut self, timestamp: i32, price: i32) {
76+
self.prices.insert(timestamp, price);
77+
self.max_time = self.max_time.max(timestamp);
78+
self.max_prices.push((price, timestamp));
79+
self.min_prices.push((Reverse(price), timestamp));
80+
}
81+
82+
fn current(&self) -> i32 {
83+
*self.prices.get(&self.max_time).unwrap()
84+
}
85+
86+
fn maximum(&mut self) -> i32 {
87+
while let Some(&(p, t)) = self.max_prices.peek() {
88+
if *self.prices.get(&t).unwrap() != p {
89+
self.max_prices.pop();
90+
} else {
91+
return p;
92+
}
93+
}
94+
95+
unimplemented!();
96+
}
97+
98+
fn minimum(&mut self) -> i32 {
99+
while let Some(&(Reverse(p), t)) = self.min_prices.peek() {
100+
if *self.prices.get(&t).unwrap() != p {
101+
self.min_prices.pop();
102+
} else {
103+
return p;
104+
}
105+
}
106+
107+
unimplemented!();
108+
}
109+
}
110+
111+
/**
112+
* Your StockPrice object will be instantiated and called as such:
113+
* let obj = StockPrice::new();
114+
* obj.update(timestamp, price);
115+
* let ret_2: i32 = obj.current();
116+
* let ret_3: i32 = obj.maximum();
117+
* let ret_4: i32 = obj.minimum();
118+
*/
119+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# 2034. 股票价格波动
2+
给你一支股票价格的数据流。数据流中每一条记录包含一个 **时间戳** 和该时间点股票对应的 **价格**
3+
4+
不巧的是,由于股票市场内在的波动性,股票价格记录可能不是按时间顺序到来的。某些情况下,有的记录可能是错的。如果两个有相同时间戳的记录出现在数据流中,前一条记录视为错误记录,后出现的记录 **更正** 前一条错误的记录。
5+
6+
请你设计一个算法,实现:
7+
8+
* **更新** 股票在某一时间戳的股票价格,如果有之前同一时间戳的价格,这一操作将 **更正** 之前的错误价格。
9+
* 找到当前记录里 **最新股票价格****最新股票价格** 定义为时间戳最晚的股票价格。
10+
* 找到当前记录里股票的 **最高价格**
11+
* 找到当前记录里股票的 **最低价格**
12+
13+
请你实现 `StockPrice` 类:
14+
15+
* `StockPrice()` 初始化对象,当前无股票价格记录。
16+
* `void update(int timestamp, int price)` 在时间点 `timestamp` 更新股票价格为 `price`
17+
* `int current()` 返回股票 **最新价格**
18+
* `int maximum()` 返回股票 **最高价格**
19+
* `int minimum()` 返回股票 **最低价格**
20+
21+
#### 示例 1:
22+
<pre>
23+
<strong>输入:</strong>
24+
["StockPrice", "update", "update", "current", "maximum", "update", "maximum", "update", "minimum"]
25+
[[], [1, 10], [2, 5], [], [], [1, 3], [], [4, 2], []]
26+
<strong>输出:</strong>
27+
[null, null, null, 5, 10, null, 5, null, 2]
28+
<strong>解释:</strong>
29+
StockPrice stockPrice = new StockPrice();
30+
stockPrice.update(1, 10); // 时间戳为 [1] ,对应的股票价格为 [10] 。
31+
stockPrice.update(2, 5); // 时间戳为 [1,2] ,对应的股票价格为 [10,5] 。
32+
stockPrice.current(); // 返回 5 ,最新时间戳为 2 ,对应价格为 5 。
33+
stockPrice.maximum(); // 返回 10 ,最高价格的时间戳为 1 ,价格为 10 。
34+
stockPrice.update(1, 3); // 之前时间戳为 1 的价格错误,价格更新为 3 。
35+
// 时间戳为 [1,2] ,对应股票价格为 [3,5] 。
36+
stockPrice.maximum(); // 返回 5 ,更正后最高价格为 5 。
37+
stockPrice.update(4, 2); // 时间戳为 [1,2,4] ,对应价格为 [3,5,2] 。
38+
stockPrice.minimum(); // 返回 2 ,最低价格时间戳为 4 ,价格为 2 。
39+
</pre>
40+
41+
#### 提示:
42+
* <code>1 <= timestamp, price <= 10<sup>9</sup></code>
43+
* `update``current``maximum``minimum` **** 调用次数不超过 <code>10<sup>5</sup></code> 。
44+
* `current``maximum``minimum` 被调用时,`update` 操作 **至少** 已经被调用过 **一次**
45+
46+
## 题解 (Rust)
47+
48+
### 1. 题解
49+
```Rust
50+
use std::cmp::Reverse;
51+
use std::collections::BinaryHeap;
52+
use std::collections::HashMap;
53+
54+
struct StockPrice {
55+
prices: HashMap<i32, i32>,
56+
max_time: i32,
57+
max_prices: BinaryHeap<(i32, i32)>,
58+
min_prices: BinaryHeap<(Reverse<i32>, i32)>,
59+
}
60+
61+
/**
62+
* `&self` means the method takes an immutable reference.
63+
* If you need a mutable reference, change it to `&mut self` instead.
64+
*/
65+
impl StockPrice {
66+
fn new() -> Self {
67+
Self {
68+
prices: HashMap::new(),
69+
max_time: 0,
70+
max_prices: BinaryHeap::new(),
71+
min_prices: BinaryHeap::new(),
72+
}
73+
}
74+
75+
fn update(&mut self, timestamp: i32, price: i32) {
76+
self.prices.insert(timestamp, price);
77+
self.max_time = self.max_time.max(timestamp);
78+
self.max_prices.push((price, timestamp));
79+
self.min_prices.push((Reverse(price), timestamp));
80+
}
81+
82+
fn current(&self) -> i32 {
83+
*self.prices.get(&self.max_time).unwrap()
84+
}
85+
86+
fn maximum(&mut self) -> i32 {
87+
while let Some(&(p, t)) = self.max_prices.peek() {
88+
if *self.prices.get(&t).unwrap() != p {
89+
self.max_prices.pop();
90+
} else {
91+
return p;
92+
}
93+
}
94+
95+
unimplemented!();
96+
}
97+
98+
fn minimum(&mut self) -> i32 {
99+
while let Some(&(Reverse(p), t)) = self.min_prices.peek() {
100+
if *self.prices.get(&t).unwrap() != p {
101+
self.min_prices.pop();
102+
} else {
103+
return p;
104+
}
105+
}
106+
107+
unimplemented!();
108+
}
109+
}
110+
111+
/**
112+
* Your StockPrice object will be instantiated and called as such:
113+
* let obj = StockPrice::new();
114+
* obj.update(timestamp, price);
115+
* let ret_2: i32 = obj.current();
116+
* let ret_3: i32 = obj.maximum();
117+
* let ret_4: i32 = obj.minimum();
118+
*/
119+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use std::cmp::Reverse;
2+
use std::collections::BinaryHeap;
3+
use std::collections::HashMap;
4+
5+
struct StockPrice {
6+
prices: HashMap<i32, i32>,
7+
max_time: i32,
8+
max_prices: BinaryHeap<(i32, i32)>,
9+
min_prices: BinaryHeap<(Reverse<i32>, i32)>,
10+
}
11+
12+
/**
13+
* `&self` means the method takes an immutable reference.
14+
* If you need a mutable reference, change it to `&mut self` instead.
15+
*/
16+
impl StockPrice {
17+
fn new() -> Self {
18+
Self {
19+
prices: HashMap::new(),
20+
max_time: 0,
21+
max_prices: BinaryHeap::new(),
22+
min_prices: BinaryHeap::new(),
23+
}
24+
}
25+
26+
fn update(&mut self, timestamp: i32, price: i32) {
27+
self.prices.insert(timestamp, price);
28+
self.max_time = self.max_time.max(timestamp);
29+
self.max_prices.push((price, timestamp));
30+
self.min_prices.push((Reverse(price), timestamp));
31+
}
32+
33+
fn current(&self) -> i32 {
34+
*self.prices.get(&self.max_time).unwrap()
35+
}
36+
37+
fn maximum(&mut self) -> i32 {
38+
while let Some(&(p, t)) = self.max_prices.peek() {
39+
if *self.prices.get(&t).unwrap() != p {
40+
self.max_prices.pop();
41+
} else {
42+
return p;
43+
}
44+
}
45+
46+
unimplemented!();
47+
}
48+
49+
fn minimum(&mut self) -> i32 {
50+
while let Some(&(Reverse(p), t)) = self.min_prices.peek() {
51+
if *self.prices.get(&t).unwrap() != p {
52+
self.min_prices.pop();
53+
} else {
54+
return p;
55+
}
56+
}
57+
58+
unimplemented!();
59+
}
60+
}
61+
62+
/**
63+
* Your StockPrice object will be instantiated and called as such:
64+
* let obj = StockPrice::new();
65+
* obj.update(timestamp, price);
66+
* let ret_2: i32 = obj.current();
67+
* let ret_3: i32 = obj.maximum();
68+
* let ret_4: i32 = obj.minimum();
69+
*/

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@
930930
[2027][2027l]|[Minimum Moves to Convert String][2027] |![rs]
931931
[2028][2028l]|[Find Missing Observations][2028] |![rs]
932932
[2032][2032l]|[Two Out of Three][2032] |![py]
933+
[2034][2034l]|[Stock Price Fluctuation ][2034] |![rs]
933934
[2037][2037l]|[Minimum Number of Moves to Seat Everyone][2037] |![rs]
934935
[2038][2038l]|[Remove Colored Pieces if Both Neighbors are the Same Color][2038] |![rs]
935936
[2042][2042l]|[Check if Numbers Are Ascending in a Sentence][2042] |![py]
@@ -2081,6 +2082,7 @@
20812082
[2027]:Problemset/2027-Minimum%20Moves%20to%20Convert%20String/README.md#2027-minimum-moves-to-convert-string
20822083
[2028]:Problemset/2028-Find%20Missing%20Observations/README.md#2028-find-missing-observations
20832084
[2032]:Problemset/2032-Two%20Out%20of%20Three/README.md#2032-two-out-of-three
2085+
[2034]:Problemset/2034-Stock%20Price%20Fluctuation/README.md#2034-stock-price-fluctuation
20842086
[2037]:Problemset/2037-Minimum%20Number%20of%20Moves%20to%20Seat%20Everyone/README.md#2037-minimum-number-of-moves-to-seat-everyone
20852087
[2038]:Problemset/2038-Remove%20Colored%20Pieces%20if%20Both%20Neighbors%20are%20the%20Same%20Color/README.md#2038-remove-colored-pieces-if-both-neighbors-are-the-same-color
20862088
[2042]:Problemset/2042-Check%20if%20Numbers%20Are%20Ascending%20in%20a%20Sentence/README.md#2042-check-if-numbers-are-ascending-in-a-sentence
@@ -3237,6 +3239,7 @@
32373239
[2027l]:https://leetcode.com/problems/minimum-moves-to-convert-string/
32383240
[2028l]:https://leetcode.com/problems/find-missing-observations/
32393241
[2032l]:https://leetcode.com/problems/two-out-of-three/
3242+
[2034l]:https://leetcode.com/problems/stock-price-fluctuation/
32403243
[2037l]:https://leetcode.com/problems/minimum-number-of-moves-to-seat-everyone/
32413244
[2038l]:https://leetcode.com/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color/
32423245
[2042l]:https://leetcode.com/problems/check-if-numbers-are-ascending-in-a-sentence/

README_CN.md

+3
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@
930930
[2027][2027l]|[转换字符串的最少操作次数][2027] |![rs]
931931
[2028][2028l]|[找出缺失的观测数据][2028] |![rs]
932932
[2032][2032l]|[至少在两个数组中出现的值][2032] |![py]
933+
[2034][2034l]|[股票价格波动][2034] |![rs]
933934
[2037][2037l]|[使每位学生都有座位的最少移动次数][2037] |![rs]
934935
[2038][2038l]|[如果相邻两个颜色均相同则删除当前颜色][2038] |![rs]
935936
[2042][2042l]|[检查句子中的数字是否递增][2042] |![py]
@@ -2081,6 +2082,7 @@
20812082
[2027]:Problemset/2027-Minimum%20Moves%20to%20Convert%20String/README_CN.md#2027-转换字符串的最少操作次数
20822083
[2028]:Problemset/2028-Find%20Missing%20Observations/README_CN.md#2028-找出缺失的观测数据
20832084
[2032]:Problemset/2032-Two%20Out%20of%20Three/README_CN.md#2032-至少在两个数组中出现的值
2085+
[2034]:Problemset/2034-Stock%20Price%20Fluctuation/README_CN.md#2034-股票价格波动
20842086
[2037]:Problemset/2037-Minimum%20Number%20of%20Moves%20to%20Seat%20Everyone/README_CN.md#2037-使每位学生都有座位的最少移动次数
20852087
[2038]:Problemset/2038-Remove%20Colored%20Pieces%20if%20Both%20Neighbors%20are%20the%20Same%20Color/README_CN.md#2038-如果相邻两个颜色均相同则删除当前颜色
20862088
[2042]:Problemset/2042-Check%20if%20Numbers%20Are%20Ascending%20in%20a%20Sentence/README_CN.md#2042-检查句子中的数字是否递增
@@ -3237,6 +3239,7 @@
32373239
[2027l]:https://leetcode.cn/problems/minimum-moves-to-convert-string/
32383240
[2028l]:https://leetcode.cn/problems/find-missing-observations/
32393241
[2032l]:https://leetcode.cn/problems/two-out-of-three/
3242+
[2034l]:https://leetcode.cn/problems/stock-price-fluctuation/
32403243
[2037l]:https://leetcode.cn/problems/minimum-number-of-moves-to-seat-everyone/
32413244
[2038l]:https://leetcode.cn/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color/
32423245
[2042l]:https://leetcode.cn/problems/check-if-numbers-are-ascending-in-a-sentence/

0 commit comments

Comments
 (0)