2034. 股票价格波动 【有序集合、优先队列】

11 阅读2分钟

2034. 股票价格波动

方法: 哈希表 + 有序集合

from sortedcontainers import SortedList 

class StockPrice:

    def __init__(self): # 最大时间戳、哈希表、有序集合 # O(1)
        #  哈希: 记录时间戳 和 价格
        # 维护 最大的时间戳
        # 有序集合 维护 最大值 最小值
        self.price = SortedList() # 有序集合 价格
        self.timePriceMap = {}
        self.maxTimestamp = 0       

    def update(self, timestamp: int, price: int) -> None:  # O(log n)
        if timestamp in self.timePriceMap:
            self.price.discard(self.timePriceMap[timestamp]) ## 修改 所有值
        # 不在, 直接加入
        self.price.add(price)
        self.timePriceMap[timestamp] = price 
        if timestamp > self.maxTimestamp:
            self.maxTimestamp = timestamp

    def current(self) -> int: # O(1)
        return self.timePriceMap[self.maxTimestamp]

    def maximum(self) -> int: # O(log n)
        return self.price[-1]

    def minimum(self) -> int: # O(log n)
        return self.price[0]


# Your StockPrice object will be instantiated and called as such:
# obj = StockPrice()
# obj.update(timestamp,price)
# param_2 = obj.current()
# param_3 = obj.maximum()
# param_4 = obj.minimum()

image.png

class StockPrice {
public:
    StockPrice() {
        this->maxTimestamp = 0;
    }
    
    void update(int timestamp, int price) {
        if (timestamp > maxTimestamp){
            maxTimestamp = timestamp;
        }

        int prevPrice = timePriceMap.count(timestamp) ? timePriceMap[timestamp] : 0;
        timePriceMap[timestamp] = price;
        if (prevPrice > 0){
            auto it = prices.find(prevPrice);
            if (it != prices.end()){
                prices.erase(it); // !!! 有可能时间戳不一样, 但值一样
            }
        }
        prices.emplace(price);
    }
    
    int current() {
        return timePriceMap[maxTimestamp];
    }
    
    int maximum() {
        return *prices.rbegin();
    }
    
    int minimum() {
        return *prices.begin();
    }
private:
    int maxTimestamp;
    unordered_map<int, int> timePriceMap;
    multiset<int> prices;
};

/**
 * Your StockPrice object will be instantiated and called as such:
 * StockPrice* obj = new StockPrice();
 * obj->update(timestamp,price);
 * int param_2 = obj->current();
 * int param_3 = obj->maximum();
 * int param_4 = obj->minimum();
 */

方法:哈希表 + 两个优先队列

class StockPrice:
    # 删除过期价格不一定要在更新操作中完成,而是可以在返回股票最高价格操作和返回股票最低价格操作中完成,即延迟删除。

    def __init__(self): # O(1)
        self.maxPrice = []
        self.minPrice = []
        self.timePriceMap = {}
        self.maxTimestamp = 0

    def update(self, timestamp: int, price: int) -> None: # O(log n)
        heappush(self.maxPrice, (-price, timestamp)) 
        heappush(self.minPrice, (price, timestamp))
        self.timePriceMap[timestamp] = price  
        if timestamp > self.maxTimestamp:
            self.maxTimestamp = timestamp

    def current(self) -> int: # O(1)
        return self.timePriceMap[self.maxTimestamp]

    def maximum(self) -> int: # O(log n)
        while True:
            price, timestamp = self.maxPrice[0] # 查看 大根
            if -price == self.timePriceMap[timestamp]:
                return -price 
            heappop(self.maxPrice)  # 旧的值 弹出

    def minimum(self) -> int: # O(log n)
        while True:
            price, timestamp = self.minPrice[0]
            if price == self.timePriceMap[timestamp]: # 已是最新 返回
                return price 
            heappop(self.minPrice) # 旧的值 弹出


# Your StockPrice object will be instantiated and called as such:
# obj = StockPrice()
# obj.update(timestamp,price)
# param_2 = obj.current()
# param_3 = obj.maximum()
# param_4 = obj.minimum()

image.png

typedef pair<int, int> pii;

class StockPrice {// 总体空间复杂度 O(n)
public:
    StockPrice() {// O(1)
        this->maxTimestamp = 0;
    }
    
    void update(int timestamp, int price) { // O(log n)
        if (timestamp > maxTimestamp){
            maxTimestamp = timestamp;
        }
        timePriceMap[timestamp] = price;
        pqMax.emplace(price, timestamp);
        pqMin.emplace(price, timestamp);
    }
    
    int current() {// O(1)
        return timePriceMap[maxTimestamp];
    }
    
    int maximum() {// O(log n)
        while (true){
            int price = pqMax.top().first, timestamp = pqMax.top().second;
            if (price == timePriceMap[timestamp]){
                return price;
            }
            pqMax.pop();
        }

    }
    
    int minimum() { // O(log n)
        while (true){
            int price = pqMin.top().first, timestamp = pqMin.top().second;
            if (price == timePriceMap[timestamp]){
                return price;
            }
            pqMin.pop();
        }

    }
private:
    int maxTimestamp;
    unordered_map<int, int> timePriceMap;
    priority_queue<pii, vector<pii>, less<pii>> pqMax;
    priority_queue<pii, vector<pii>, greater<pii>> pqMin;
};

/**
 * Your StockPrice object will be instantiated and called as such:
 * StockPrice* obj = new StockPrice();
 * obj->update(timestamp,price);
 * int param_2 = obj->current();
 * int param_3 = obj->maximum();
 * int param_4 = obj->minimum();
 */