-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStockPrice.java
134 lines (116 loc) · 4.88 KB
/
StockPrice.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package solutions;
// [Problem] https://leetcode.com/problems/stock-price-fluctuation
import java.util.*;
// Min & Max Heaps
class StockPriceHeap {
Map<Integer, Integer> records;
Queue<StockRecord> minHeap;
Queue<StockRecord> maxHeap;
StockRecord latestRecord;
// O(n) space where n = number of prices
public StockPriceHeap() {
records = new HashMap<>();
minHeap = new PriorityQueue<>((a, b) -> a.price - b.price);
maxHeap = new PriorityQueue<>((a, b) -> b.price - a.price);
}
// O(logn) time
public void update(int timestamp, int price) {
StockRecord record = new StockRecord(timestamp, price);
records.put(timestamp, price);
minHeap.add(record);
maxHeap.add(record);
if (latestRecord == null || timestamp >= latestRecord.timestamp) {
latestRecord = record;
}
}
// O(1) time
public int current() {
return latestRecord.price;
}
// O(k) time, where k = number of outdated max records
public int maximum() {
StockRecord maxRecord = maxHeap.peek();
while (records.get(maxRecord.timestamp) != maxRecord.price) {
maxHeap.poll();
maxRecord = maxHeap.peek();
}
return maxRecord.price;
}
// O(k) time, where k = number of outdated min records
public int minimum() {
StockRecord minRecord = minHeap.peek();
while (records.get(minRecord.timestamp) != minRecord.price) {
minHeap.poll();
minRecord = minHeap.peek();
}
return minRecord.price;
}
// Test
public static void main(String[] args) {
StockPriceHeap stockPrice = new StockPriceHeap();
stockPrice.update(1, 10); // Timestamps are [1] with corresponding prices [10].
stockPrice.update(2, 5); // Timestamps are [1,2] with corresponding prices [10,5].
System.out.println(stockPrice.current()); // return 5, the latest timestamp is 2 with the price being 5.
System.out.println(stockPrice.maximum()); // return 10, the maximum price is 10 at timestamp 1.
stockPrice.update(1, 3); // Timestamps are [1,2] with corresponding prices [3,5].
System.out.println(stockPrice.maximum()); // return 5, the maximum price is 5 after the correction.
stockPrice.update(4, 2); // Timestamps are [1,2,4] with corresponding prices [3,5,2].
System.out.println(stockPrice.minimum()); // return 2, the minimum price is 2 at timestamp 4.
}
}
class StockRecord {
int price;
int timestamp;
public StockRecord(int timestamp, int price) {
this.timestamp = timestamp;
this.price = price;
}
}
// Two TreeMaps
class StockPrice {
TreeMap<Integer, Integer> pricePerTimestamp;
TreeMap<Integer, Set<Integer>> timestampsPerPrice;
// O(n) space
public StockPrice() {
pricePerTimestamp = new TreeMap<>();
timestampsPerPrice = new TreeMap<>();
}
// O(logn) time
public void update(int timestamp, int price) {
if (pricePerTimestamp.containsKey(timestamp)) {
int prevPrice = pricePerTimestamp.get(timestamp);
Set<Integer> prevPriceTimestamps = timestampsPerPrice.get(prevPrice);
prevPriceTimestamps.remove(timestamp);
if (prevPriceTimestamps.isEmpty()) {
timestampsPerPrice.remove(prevPrice);
}
}
pricePerTimestamp.put(timestamp, price);
timestampsPerPrice.putIfAbsent(price, new HashSet<>());
timestampsPerPrice.get(price).add(timestamp);
}
// O(logn) time
public int current() {
return pricePerTimestamp.lastEntry().getValue();
}
// O(logn) time
public int maximum() {
return timestampsPerPrice.lastKey();
}
// O(logn) time
public int minimum() {
return timestampsPerPrice.firstKey();
}
// Test
public static void main(String[] args) {
StockPrice stockPrice = new StockPrice();
stockPrice.update(1, 10); // Timestamps are [1] with corresponding prices [10].
stockPrice.update(2, 5); // Timestamps are [1,2] with corresponding prices [10,5].
System.out.println(stockPrice.current()); // return 5, the latest timestamp is 2 with the price being 5.
System.out.println(stockPrice.maximum()); // return 10, the maximum price is 10 at timestamp 1.
stockPrice.update(1, 3); // Timestamps are [1,2] with corresponding prices [3,5].
System.out.println(stockPrice.maximum()); // return 5, the maximum price is 5 after the correction.
stockPrice.update(4, 2); // Timestamps are [1,2,4] with corresponding prices [3,5,2].
System.out.println(stockPrice.minimum()); // return 2, the minimum price is 2 at timestamp 4.
}
}