A Range Module is a module that tracks ranges of numbers. Your task is to design and implement the following interfaces in an efficient manner.
-
addRange(int left, int right)
Adds the half-open interval[left, right)
, tracking every real number in that interval. Adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval[left, right)
that are not already tracked. -
queryRange(int left, int right)
Returns true if and only if every real number in the interval[left, right)
is currently being tracked. -
removeRange(int left, int right)
Stops tracking every real number currently being tracked in the interval[left, right)
.Example 1:
addRange(10, 20): null removeRange(14, 16): null queryRange(10, 14): true (Every number in [10, 14) is being tracked) queryRange(13, 15): false (Numbers like 14, 14.03, 14.17 in [13, 15) are not being tracked) queryRange(16, 17): true (The number 16 in [16, 17) is still being tracked, despite the remove operation)
Note:
- A half open interval
[left, right)
denotes all real numbersleft <= x < right
. -
0 < left < right < 10^9
in all calls toaddRange, queryRange, removeRange
. - The total number of calls to
addRange
in a single test case is at most1000
. - The total number of calls to
queryRange
in a single test case is at most5000
. - The total number of calls to
removeRange
in a single test case is at most1000
.
题目:
三种操作:
1、加入线段
2、删除线段
3、是否命中线段
边界有点多,不是很好写!
#include <iostream> #include <iostream> #include <algorithm> #include <unordered_map> #include <unordered_set> #include <set> #include <vector> #include <map> #include <set> #include <queue> #include <stack> #include <string> #include <math.h> using namespace std; class RangeModule { public: RangeModule(){} void addRange(int left, int right) { addRangeHelper(left, right, 0); addconnect(); printhelper(); } bool queryRange(int left, int right) { return queryRangeHelper(left, right, 0); } void removeRange(int left, int right) { removeRangeHelper(left, right, 0); addconnect(); printhelper(); } private: vector<pair<int, int>> all; bool queryRangeHelper(int left, int right, int startIndex) { for (int i = max(startIndex, 0); i < all.size(); i++) { if (left >= all[i].second) continue; else if (left >= all[i].first && right <= all[i].second) //只有刚好在某一个块内部 才能命中 return true; else return false; } return false; } void addconnect() { if (all.size() >= 2) { int i = 0; while (i < all.size() - 1) { if (all[i].second == all[i + 1].first) { all[i].second = all[i + 1].second; all.erase(all.begin() + i + 1); } else if (all[i].first == all[i].second) //没有检测最后一个,要double check一下 { all.erase(all.begin() + i); } else i ++; } } //double check if (!all.empty() && all.back().first == all.back().second) all.pop_back(); } void addRangeHelper(int left, int right, int startIndex) { if (all.empty()) { all.push_back({left, right}); return; } for (int i = max(startIndex, 0); i < all.size(); i++) { if (left >= all[i].second) //在当前的后面 continue; else if (right <= all[i].first) { all.insert(all.begin() + i, {left, right}); break; } else if (all[i].first <= left && right <= all[i].second) //插入情况 1 { return; } else if (left <= all[i].first && right <= all[i].second) // 插入情况 3 { all[i].first = left; return; } else if (left <= all[i].first && right > all[i].second) // 插入情况 2 { all[i].first = left; addRangeHelper(all[i].second, right, i - 2); return; } else if (left > all[i].first && right > all[i].second) // 插入情况 4 { addRangeHelper(all[i].second, right, i - 2); return; } } if (left >= all.back().second) //情况5 可能比现有的所有都要后面 all.push_back({left,right}); } void removeRangeHelper(int left, int right, int startIndex) { for (int i = max(startIndex, 0); i < all.size(); i ++) { if (left >= all[i].second) continue; else if (right <= all[i].first) break; else if (left == all[i].first && right == all[i].second) //完全和当前的重合,那就直接删除 { all.erase(all.begin() + i); return; } else if (all[i].first <= left && right <= all[i].second) //删除情况3 { all.insert(all.begin() + i + 1, {right, all[i].second}); all[i].second = left; if (left == all[i].first) all.erase(all.begin() + i); return; } else if (left <= all[i].first && right <= all[i].second) // 删除情况1 { removeRangeHelper(all[i].first, right, i - 2); return; } else if (left <= all[i].first && right > all[i].second) // 删除情况2 { int tmp = all[i].second; all.erase(all.begin() + i); removeRangeHelper(tmp, right, i - 2); return; } else if (left > all[i].first && right > all[i].second) // 删除情况4 { int tmp = all[i].second; all[i].second = left; removeRangeHelper(tmp, right, i - 2); return; } } } void printhelper() { for (auto it : all) cout<<it.first<<"-"<<it.second<<" "; cout<<endl; } }; int main() { RangeModule test; test.removeRange(7, 8); test.addRange(4, 10); cout<<test.queryRange(7, 8)<<endl; cout<<test.queryRange(5, 7)<<endl; cout<<test.queryRange(1, 8)<<endl; test.addRange(2, 6); test.addRange(4, 6); test.removeRange(3, 4); test.removeRange(5, 7); return 0; }