作者:U友50141148 | 来源:互联网 | 2023-05-18 19:10
经典linesweep问题,和perfectrectangle很类似,但是要考虑多个矩形左边界一样的情况,加个id来区分。和另一道类似的题theskylineproblem不同的是
经典line sweep问题,和 perfect rectangle 很类似,但是要考虑多个矩形左边界一样的情况,加个id来区分。
和另一道类似的题 the skyline problem 不同的是,没有很多 corner cases,对 x 排序非常简单。
难点是在 active set 里,和 merge intervals 那题一样,计算 total_y,乘以两个相邻 event 的 delta_x。
class Solution {
public:
struct interval {
int start, end;
bool operator<(const interval &i) const {
if (start == i.start)
return end < i.end;
return start < i.start;
}
};
struct edge {
int x;
interval i;
int type; // left <- 1, right <- -1
int id;
};
int rectangleArea(vectorint>>& rectangles) {
vector vec;
for (int i=0;ii){
auto rect=rectangles[i];
vec.push_back({rect[0],{rect[1],rect[3]},1,i});
vec.push_back({rect[2],{rect[1],rect[3]},-1,i});
}
sort(vec.begin(),vec.end(),[](edge e1, edge e2){
return e1.x < e2.x;
});
setint>> active_set; //
active_set.insert({vec[0].i,vec[0].id});
int prev_x=vec[0].x;
int res=0;
for (int i=1;ii){
int delta_x=vec[i].x-prev_x;
// merge interval
int s=-1,e=-1;
int total_y=0;
for (auto m:active_set){
interval i=m.first;
int id=m.second;
if (s==-1 || i.start>e){
total_y += e-s;
s = i.start; e = i.end;
}else{
e = max(e,i.end);
}
}
total_y += e-s;
res = (res + long(delta_x)*total_y) % 1000000007;
if (vec[i].type==1) active_set.insert({vec[i].i,vec[i].id});
else active_set.erase({vec[i].i,vec[i].id});
prev_x = vec[i].x;
}
return res;
}
};
时间复杂度 O(nlogn)
Reference
https://leetcode.com/problems/rectangle-area-ii/solution/
Computational Geometry - Line Sweep - 3 - Rectangles Union (Arabic)
LeetCode 850. Rectangle Area II