LeetCode-2034. 股票价格波动

给你一支股票价格的数据流。数据流中每一条记录包含一个 时间戳 和该时间点股票对应的 价格 。

不巧的是,由于股票市场内在的波动性,股票价格记录可能不是按时间顺序到来的。某些情况下,有的记录可能是错的。如果两个有相同时间戳的记录出现在数据流中,前一条记录视为错误记录,后出现的记录 更正 前一条错误的记录。

请你设计一个算法,实现:

更新 股票在某一时间戳的股票价格,如果有之前同一时间戳的价格,这一操作将 更正 之前的错误价格。
找到当前记录里 最新股票价格 。最新股票价格 定义为时间戳最晚的股票价格。
找到当前记录里股票的 最高价格 。
找到当前记录里股票的 最低价格 。
请你实现 StockPrice 类:

StockPrice() 初始化对象,当前无股票价格记录。
void update(int timestamp, int price) 在时间点 timestamp 更新股票价格为 price 。
int current() 返回股票 最新价格 。
int maximum() 返回股票 最高价格 。
int minimum() 返回股票 最低价格 。
 

示例 1:

输入:
["StockPrice", "update", "update", "current", "maximum", "update", "maximum", "update", "minimum"]
[[], [1, 10], [2, 5], [], [], [1, 3], [], [4, 2], []]
输出:
[null, null, null, 5, 10, null, 5, null, 2]

解释:
StockPrice stockPrice = new StockPrice();
stockPrice.update(1, 10); // 时间戳为 [1] ,对应的股票价格为 [10] 。
stockPrice.update(2, 5);  // 时间戳为 [1,2] ,对应的股票价格为 [10,5] 。
stockPrice.current();     // 返回 5 ,最新时间戳为 2 ,对应价格为 5 。
stockPrice.maximum();     // 返回 10 ,最高价格的时间戳为 1 ,价格为 10 。
stockPrice.update(1, 3);  // 之前时间戳为 1 的价格错误,价格更新为 3 。
                          // 时间戳为 [1,2] ,对应股票价格为 [3,5] 。
stockPrice.maximum();     // 返回 5 ,更正后最高价格为 5 。
stockPrice.update(4, 2);  // 时间戳为 [1,2,4] ,对应价格为 [3,5,2] 。
stockPrice.minimum();     // 返回 2 ,最低价格时间戳为 4 ,价格为 2 。
 

提示:

1 <= timestamp, price <= 109
update,current,maximum 和 minimum 总 调用次数不超过 105 。
current,maximum 和 minimum 被调用时,update 操作 至少 已经被调用过 一次 

思路:

股票价格随时会更新,但是每次需要求一个极值,

建立两个优先队列,分别计算最大值,最小值,优先队列的目的

就是有序,底层是大顶堆或者小顶堆的数据结构,保证每次进入队列的数据有序

其中难点有2个,一是存储stock的数据结构来在优先队列比较。需要自己写仿函数比较

二是当发生股票更新的时候如何去处理,固定的思路是已发生更改我们就去调整堆的结构

比如,将堆重排,但是我们仔细想,这样效率太低,实际上我们只用比较price,也就是价格,

只要保证每次更新的正确的时间和价格入队,参与比较,我们就只需要才出队时候,判断最大值

最小值是否过期即可。

#include
#include
#include
using namespace std;


/* 自定义stock股票结构 */
typedef struct Stock {
	int timestamp;
	int price;
}stock;

/* 仿函数自定义比较方法 */
class max_cmp {
public:
	bool operator () (const stock& x, const stock& y) {
		return (x.price < y.price);  //大根堆
	}
};

/* 仿函数自定义比较方法 */
class min_cmp {
public:
	bool operator () (const stock& x, const stock& y) {
		return (x.price > y.price);  //小根堆
	}
};

class StockPrice {
public:
	StockPrice() {
		cur_timestamp = INT_MIN;
	}

	void update(int timestamp, int price) {
		stock s;
		s.timestamp = timestamp;
		s.price = price;
		mp[timestamp] = price;
		cur_timestamp = max(cur_timestamp, timestamp);
		max_que.push(s);
		min_que.push(s);
	}


	int current() {
		return mp[cur_timestamp];
	}

	/* 延迟删除 */
	int maximum() {
		while (true) {
			int timestamp = max_que.top().timestamp;
			int price = max_que.top().price;
			/* 只有相等才说明,股票架构没有过期 */
			if (mp[timestamp] == price) {
				return price;
			}
			max_que.pop();
		}
	}
	/* 延迟删除 */
	int minimum() {
		while (true) {
			int timestamp = min_que.top().timestamp;
			int price = min_que.top().price;

			/* 只有相等才说明,股票架构没有过期 */
			if (mp[timestamp] == price) {
				return price;
			}
			min_que.pop();
		}
	}

private:
	int cur_timestamp;
	unordered_map mp;                                     /* key:timestamp, value:price */
	priority_queue, max_cmp> max_que;          /* max_que */
	priority_queue, min_cmp> min_que;          /* min_que */
};


/* 以下为优先队列测试方法,与题目无关 */
int main() {

	Stock s1, s2, s3, s4;
	s1.timestamp = 1;
	s1.price = 10;

	s2.timestamp = 2;
	s2.price = 5;

	s3.timestamp = 3;
	s3.price = 8;

	s4.timestamp = 4;
	s4.price = 7;

	priority_queue, max_cmp> max_que;          /* max_que */
	priority_queue, min_cmp> min_que;          /* min_que */

	min_que.push(s1);
	min_que.push(s2);
	min_que.push(s3);
	min_que.push(s4);

	while (!min_que.empty()) {
		stock s = min_que.top();
		cout << "time:" << s.timestamp << endl;
		cout << "price:" << s.price << endl;
		min_que.pop();
	}

	system("pause");
	return 0;
}


你可能感兴趣的:(算法,LeetCode,C++,leetcode,c++,算法)