@@ -66,42 +66,54 @@ stockPrice.minimum(); // 返回 2 ,最低价格时间戳为 4 ,价格为
66
66
67
67
<!-- 这里可写通用的实现逻辑 -->
68
68
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
+
69
86
<!-- tabs:start -->
70
87
71
88
### ** Python3**
72
89
73
90
<!-- 这里可写当前语言的特殊实现逻辑 -->
74
91
75
92
``` python
76
- from sortedcontainers import SortedDict
93
+ from sortedcontainers import SortedList
77
94
78
95
79
96
class StockPrice :
80
97
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
84
101
85
102
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)
96
108
97
109
def current (self ) -> int :
98
- return self .mp [self .last_ts ]
110
+ return self .d [self .last ]
99
111
100
112
def maximum (self ) -> int :
101
- return self .counter.keys() [- 1 ]
113
+ return self .ls [- 1 ]
102
114
103
115
def minimum (self ) -> int :
104
- return self .counter.keys() [0 ]
116
+ return self .ls [0 ]
105
117
106
118
107
119
# Your StockPrice object will be instantiated and called as such:
@@ -118,36 +130,35 @@ class StockPrice:
118
130
119
131
``` java
120
132
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 ;
124
136
125
137
public StockPrice () {
126
138
}
127
139
128
140
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);
134
145
}
135
146
}
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);
139
150
}
140
151
141
152
public int current () {
142
- return mp . get(lastTs );
153
+ return d . get(last );
143
154
}
144
155
145
156
public int maximum () {
146
- return counter . lastKey();
157
+ return ls . lastKey();
147
158
}
148
159
149
160
public int minimum () {
150
- return counter . firstKey();
161
+ return ls . firstKey();
151
162
}
152
163
}
153
164
@@ -166,35 +177,34 @@ class StockPrice {
166
177
``` cpp
167
178
class StockPrice {
168
179
public:
169
- int lastTs;
170
- unordered_map<int, int> mp;
171
- map<int, int> counter;
172
-
173
180
StockPrice() {
174
181
}
175
182
176
183
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]));
181
186
}
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);
185
190
}
186
191
187
192
int current () {
188
- return mp[lastTs ];
193
+ return d[last ];
189
194
}
190
195
191
196
int maximum() {
192
- return counter .rbegin()->first ;
197
+ return *ls .rbegin();
193
198
}
194
199
195
200
int minimum() {
196
- return counter .begin()->first ;
201
+ return *ls .begin();
197
202
}
203
+
204
+ private:
205
+ unordered_map<int, int> d;
206
+ multiset<int > ls;
207
+ int last = 0;
198
208
};
199
209
200
210
/* *
@@ -211,52 +221,57 @@ public:
211
221
212
222
``` go
213
223
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
217
227
}
218
228
219
229
func Constructor () StockPrice {
220
230
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 ,
223
234
}
224
235
}
225
236
226
237
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
+ }
234
246
} else {
235
- this.counter. Put(old, cnt-1 )
247
+ rbt. Put (key, value )
236
248
}
237
249
}
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)
240
256
}
241
257
242
258
func (this *StockPrice ) Current () int {
243
- return this.mp [this.lastTs ]
259
+ return this.d [this.last ]
244
260
}
245
261
246
262
func (this *StockPrice ) Maximum () int {
247
- return this.counter .Right().Key.(int)
263
+ return this.ls .Right ().Key .(int )
248
264
}
249
265
250
266
func (this *StockPrice ) Minimum () int {
251
- return this.counter .Left().Key.(int)
267
+ return this.ls .Left ().Key .(int )
252
268
}
253
269
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
258
273
}
259
- return val.(int)
274
+ return b
260
275
}
261
276
262
277
/* *
0 commit comments