第 444 场周赛——设计路由器
题目
题解
第二题就把我的上分梦击碎了,我的办法超时了差几个样例才能通过,需要对getCount进行优化。赛后看了灵神视频复盘。先入先出让我们首当其冲想到的就是通过队列存储,然后对于是否重复可以用set集合保存查询,但是set无法对三个参数进行哈希操作,需要我们提供一个哈希函数。getCount函数要求我们返回等于destination,timestamp在[startTime,endTime]之间的值,那我们可以将destination相同的分成一组,题目说如果超过限制将会把旧包丢出放入新包,那我们考虑对map中元素的删除,那我们可以多一维表示队头,然后startTime和endTime的位置用二分查找,最后中间的个数就是满足条件的数据包个数。
参考代码
//哈希函数
struct TupleHash {
template<typename T>
static void hash_combine(size_t& seed, const T& v) {
seed ^= hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
size_t operator()(const tuple<int, int, int>& t) const {
auto& [a, b, c] = t;
size_t seed = 0;
hash_combine(seed, a);
hash_combine(seed, b);
hash_combine(seed, c);
return seed;
}
};
class Router {
int memory_limit;
queue<tuple<int, int, int>> packet_q;
unordered_set<tuple<int, int, int>, TupleHash> packet_set;
unordered_map<int, pair<vector<int>, int>> dest_to_timestamps;
public:
Router(int memoryLimit) {
memory_limit = memoryLimit;
}
bool addPacket(int source, int destination, int timestamp) {
auto packet = make_tuple(source, destination, timestamp);
if(!packet_set.insert(packet).second) return false; //set的insert返回值是一个pair<iterator, bool>,first指向插入元素的迭代器,second表示是否插入成功。
if(packet_q.size() == memory_limit) forwardPacket();
packet_q.push(packet);
dest_to_timestamps[destination].first.push_back(timestamp);
return true;
}
vector<int> forwardPacket() {
if(packet_q.empty()) return {};
auto packet = packet_q.front();
packet_q.pop();
packet_set.erase(packet);
auto [source, destination, timestamp] = packet;
dest_to_timestamps[destination].second++;
return {source, destination, timestamp};
}
int getCount(int destination, int startTime, int endTime) {
auto& [timestamp, head] = dest_to_timestamps[destination];
auto left = ranges::lower_bound(timestamp.begin() + head, timestamp.end(), startTime);
auto right = ranges::upper_bound(timestamp.begin() + head, timestamp.end(), endTime);
return right - left;
}
};
/**
* Your Router object will be instantiated and called as such:
* Router* obj = new Router(memoryLimit);
* bool param_1 = obj->addPacket(source,destination,timestamp);
* vector<int> param_2 = obj->forwardPacket();
* int param_3 = obj->getCount(destination,startTime,endTime);
*/

浙公网安备 33010602011771号