陕西住房建设部网站中国seo
题目比较复杂,主要体现在流程很长,就是队列加二分的操作
难点1:深拷贝
主要问题1,看下面这段核心代码:
int getCount(int destination, int startTime, int endTime) {auto times = dest2times[destination];int ans = 0;auto lower_it = lower_bound(times.begin(), times.end(), startTime);size_t lower_idx = lower_it - times.begin();auto upper_it = upper_bound(times.begin(), times.end(), endTime);size_t upper_idx = upper_it - times.begin();ans = upper_idx - lower_idx;return ans;}
乍一看是 O ( l o g N ) O(logN) O(logN) 的操作,但实际上,第一步取出来的时候,这一步是深拷贝,就已经花费了 O ( N ) O(N) O(N) 的时间,所以,除了size可以深拷贝,在把较大的数据结构取出来时,一定要注意避免类似的操作。
难点2:二分
上述代码,都减去了times.begin(),其实是重复操作,用下面的代码更为简洁
int getCount(int destination, int startTime, int endTime) {auto it1 = lower_bound(dest2times[destination].begin(), dest2times[destination].end(), startTime);auto it2 = upper_bound(dest2times[destination].begin(), dest2times[destination].end(), endTime);return it2-it1;}
upper_bound:找到第一个大于目标数的位置
lower_bound:找到第一个大于等于目标数的位置
直接用bound的返回值去减,就可以得到元素数目,若是想得到对应的索引,则需要去减begin()
在非强二分考察题目时,用bound是更为省时、简单的操作。
附ac代码
typedef tuple<int, int, int> T;
typedef deque<int> V;
class Router {
set<T> packets;
map<int, V> dest2times;
queue<T> q;
int limit;
public:Router(int memoryLimit) {limit = memoryLimit;}bool addPacket(int source, int destination, int timestamp) {T t1(source, destination, timestamp);if(packets.count(t1))return false;if(q.size() == limit){T t2 = q.front();dest2times[get<1>(t2)].pop_front();packets.erase(t2);q.pop();}dest2times[destination].push_back(timestamp);q.push(t1);packets.insert(t1);return true;}vector<int> forwardPacket() {if(q.size() == 0)return vector<int>{};T t2 = q.front();dest2times[get<1>(t2)].pop_front();packets.erase(t2);q.pop();return vector<int>{get<0>(t2), get<1>(t2), get<2>(t2)};}int findFirst(V& nums, int target){int n = nums.size();int l = 0, r = n-1;while(l<r){int mid = l + (r-l)/2;if(nums[mid] < target)l = mid+1;else r = mid;}return l;}int findLast(V& nums, int target){int n = nums.size();int l = 0, r = n-1;while(l<r){int mid = l + (r-l+1)/2;if(nums[mid] > target)r = mid-1;else l = mid;}return l;}int getCount(int destination, int startTime, int endTime) {int ans = 0;int start = findFirst(dest2times[destination], startTime);int end = findLast(dest2times[destination], endTime);if(dest2times[destination][start] >= startTime and dest2times[destination][end] <= endTime)ans = end-start+1;return ans;}
};/*** 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);*/