Skip to content

Commit 39c8496

Browse files
authored
feat: add solutions to lc problem: No.2034 (#1761)
No.2034.Stock Price Fluctuation
1 parent 10e1921 commit 39c8496

File tree

6 files changed

+232
-204
lines changed

6 files changed

+232
-204
lines changed

solution/2000-2099/2034.Stock Price Fluctuation/README.md

+83-68
Original file line numberDiff line numberDiff line change
@@ -66,42 +66,54 @@ stockPrice.minimum(); // 返回 2 ,最低价格时间戳为 4 ,价格为
6666

6767
<!-- 这里可写通用的实现逻辑 -->
6868

69+
**方法一:哈希表 + 有序集合**
70+
71+
我们定义以下几个数据结构或变量,其中:
72+
73+
- `d`:表示一个哈希表,用于存储时间戳和对应的价格;
74+
- `ls`:表示一个有序集合,用于存储所有的价格;
75+
- `last`:表示最后一次更新的时间戳。
76+
77+
那么,我们可以得到以下几个操作:
78+
79+
- `update(timestamp, price)`:更新时间戳 `timestamp` 对应的价格为 `price`。如果 `timestamp` 已经存在,那么我们需要先将其对应的价格从有序集合中删除,再将其更新为 `price`。否则,我们直接将其更新为 `price`。然后,我们需要更新 `last``max(last, timestamp)`。时间复杂度为 $O(\log n)$。
80+
- `current()`:返回 `last` 对应的价格。时间复杂度为 $O(1)$。
81+
- `maximum()`:返回有序集合中的最大值。时间复杂度为 $O(\log n)$。
82+
- `minimum()`:返回有序集合中的最小值。时间复杂度为 $O(\log n)$。
83+
84+
空间复杂度为 $O(n)$。其中,$n$ 为 `update` 操作的次数。
85+
6986
<!-- tabs:start -->
7087

7188
### **Python3**
7289

7390
<!-- 这里可写当前语言的特殊实现逻辑 -->
7491

7592
```python
76-
from sortedcontainers import SortedDict
93+
from sortedcontainers import SortedList
7794

7895

7996
class StockPrice:
8097
def __init__(self):
81-
self.last_ts = 0
82-
self.mp = {}
83-
self.counter = SortedDict()
98+
self.d = {}
99+
self.ls = SortedList()
100+
self.last = 0
84101

85102
def update(self, timestamp: int, price: int) -> None:
86-
if timestamp in self.mp:
87-
old_price = self.mp[timestamp]
88-
self.counter[old_price] -= 1
89-
if self.counter[old_price] == 0:
90-
del self.counter[old_price]
91-
if price not in self.counter:
92-
self.counter[price] = 0
93-
self.counter[price] += 1
94-
self.mp[timestamp] = price
95-
self.last_ts = max(self.last_ts, timestamp)
103+
if timestamp in self.d:
104+
self.ls.remove(self.d[timestamp])
105+
self.d[timestamp] = price
106+
self.ls.add(price)
107+
self.last = max(self.last, timestamp)
96108

97109
def current(self) -> int:
98-
return self.mp[self.last_ts]
110+
return self.d[self.last]
99111

100112
def maximum(self) -> int:
101-
return self.counter.keys()[-1]
113+
return self.ls[-1]
102114

103115
def minimum(self) -> int:
104-
return self.counter.keys()[0]
116+
return self.ls[0]
105117

106118

107119
# Your StockPrice object will be instantiated and called as such:
@@ -118,36 +130,35 @@ class StockPrice:
118130

119131
```java
120132
class StockPrice {
121-
private int lastTs;
122-
private Map<Integer, Integer> mp = new HashMap<>();
123-
private TreeMap<Integer, Integer> counter = new TreeMap<>();
133+
private Map<Integer, Integer> d = new HashMap<>();
134+
private TreeMap<Integer, Integer> ls = new TreeMap<>();
135+
private int last;
124136

125137
public StockPrice() {
126138
}
127139

128140
public void update(int timestamp, int price) {
129-
if (mp.containsKey(timestamp)) {
130-
int oldPrice = mp.get(timestamp);
131-
counter.put(oldPrice, counter.get(oldPrice) - 1);
132-
if (counter.get(oldPrice) == 0) {
133-
counter.remove(oldPrice);
141+
if (d.containsKey(timestamp)) {
142+
int old = d.get(timestamp);
143+
if (ls.merge(old, -1, Integer::sum) == 0) {
144+
ls.remove(old);
134145
}
135146
}
136-
mp.put(timestamp, price);
137-
counter.put(price, counter.getOrDefault(price, 0) + 1);
138-
lastTs = Math.max(lastTs, timestamp);
147+
d.put(timestamp, price);
148+
ls.merge(price, 1, Integer::sum);
149+
last = Math.max(last, timestamp);
139150
}
140151

141152
public int current() {
142-
return mp.get(lastTs);
153+
return d.get(last);
143154
}
144155

145156
public int maximum() {
146-
return counter.lastKey();
157+
return ls.lastKey();
147158
}
148159

149160
public int minimum() {
150-
return counter.firstKey();
161+
return ls.firstKey();
151162
}
152163
}
153164

@@ -166,35 +177,34 @@ class StockPrice {
166177
```cpp
167178
class StockPrice {
168179
public:
169-
int lastTs;
170-
unordered_map<int, int> mp;
171-
map<int, int> counter;
172-
173180
StockPrice() {
174181
}
175182

176183
void update(int timestamp, int price) {
177-
if (mp.count(timestamp)) {
178-
int oldPrice = mp[timestamp];
179-
--counter[oldPrice];
180-
if (counter[oldPrice] == 0) counter.erase(oldPrice);
184+
if (d.count(timestamp)) {
185+
ls.erase(ls.find(d[timestamp]));
181186
}
182-
mp[timestamp] = price;
183-
++counter[price];
184-
lastTs = max(lastTs, timestamp);
187+
d[timestamp] = price;
188+
ls.insert(price);
189+
last = max(last, timestamp);
185190
}
186191

187192
int current() {
188-
return mp[lastTs];
193+
return d[last];
189194
}
190195

191196
int maximum() {
192-
return counter.rbegin()->first;
197+
return *ls.rbegin();
193198
}
194199

195200
int minimum() {
196-
return counter.begin()->first;
201+
return *ls.begin();
197202
}
203+
204+
private:
205+
unordered_map<int, int> d;
206+
multiset<int> ls;
207+
int last = 0;
198208
};
199209

200210
/**
@@ -211,52 +221,57 @@ public:
211221

212222
```go
213223
type StockPrice struct {
214-
lastTs int
215-
mp map[int]int
216-
counter *redblacktree.Tree
224+
d map[int]int
225+
ls *redblacktree.Tree
226+
last int
217227
}
218228

219229
func Constructor() StockPrice {
220230
return StockPrice{
221-
mp: make(map[int]int),
222-
counter: redblacktree.NewWithIntComparator(),
231+
d: make(map[int]int),
232+
ls: redblacktree.NewWithIntComparator(),
233+
last: 0,
223234
}
224235
}
225236

226237
func (this *StockPrice) Update(timestamp int, price int) {
227-
if timestamp > this.lastTs {
228-
this.lastTs = timestamp
229-
}
230-
if old, ok := this.mp[timestamp]; ok {
231-
cnt := getInt(this.counter, old)
232-
if cnt == 1 {
233-
this.counter.Remove(old)
238+
merge := func(rbt *redblacktree.Tree, key, value int) {
239+
if v, ok := rbt.Get(key); ok {
240+
nxt := v.(int) + value
241+
if nxt == 0 {
242+
rbt.Remove(key)
243+
} else {
244+
rbt.Put(key, nxt)
245+
}
234246
} else {
235-
this.counter.Put(old, cnt-1)
247+
rbt.Put(key, value)
236248
}
237249
}
238-
this.mp[timestamp] = price
239-
this.counter.Put(price, getInt(this.counter, price)+1)
250+
if v, ok := this.d[timestamp]; ok {
251+
merge(this.ls, v, -1)
252+
}
253+
this.d[timestamp] = price
254+
merge(this.ls, price, 1)
255+
this.last = max(this.last, timestamp)
240256
}
241257

242258
func (this *StockPrice) Current() int {
243-
return this.mp[this.lastTs]
259+
return this.d[this.last]
244260
}
245261

246262
func (this *StockPrice) Maximum() int {
247-
return this.counter.Right().Key.(int)
263+
return this.ls.Right().Key.(int)
248264
}
249265

250266
func (this *StockPrice) Minimum() int {
251-
return this.counter.Left().Key.(int)
267+
return this.ls.Left().Key.(int)
252268
}
253269

254-
func getInt(rbt *redblacktree.Tree, key int) int {
255-
val, found := rbt.Get(key)
256-
if !found {
257-
return 0
270+
func max(a, b int) int {
271+
if a > b {
272+
return a
258273
}
259-
return val.(int)
274+
return b
260275
}
261276

262277
/**

0 commit comments

Comments
 (0)