方法一:
扫描线+数组区间更新:时间复杂度O(N*N)
class Solution {
public:
struct StateNode{
int y;
int tp;
int x1;
int x2;
void puts(int yy,int t,int xa,int xb){
y = yy; tp = t; x1 = xa; x2 = xb;
}
bool operator < (const StateNode& x) const{
if(this->y < x.y) return true;
return false;
}
};
int rectangleArea(vector<vector<int>>& rectangles) {
int N = rectangles.size();
StateNode sn[N*2];
map<int,int> mp,pm;
for(int i=0;i<N;i++){
sn[i].puts(rectangles[i][1],1,rectangles[i][0],rectangles[i][2]);
sn[i+N].puts(rectangles[i][3],-1,rectangles[i][0],rectangles[i][2]);
mp[rectangles[i][0]] = mp[rectangles[i][2]] = 1;
}
sort(sn,sn+N+N);
int M = 1;
for(map<int,int>::iterator p=mp.begin();p!=mp.end();p++){
p->second = M;
pm[M] = p->first;
M++;
}
vector<int> xv(M,0);
long long ans = 0;
long long last_y = 0;
for(int i=0;i<N+N;i++){
if(sn[i].y != last_y){
long long lenth = 0;
for(int j=1;j<M;j++) if(xv[j]) lenth += pm[j+1] - pm[j];
ans += (sn[i].y - last_y)*lenth;
last_y = sn[i].y;
}
for(int j=mp[sn[i].x1];j<mp[sn[i].x2];j++) xv[j] += sn[i].tp;
}
const long long mod = 1000000007;
return ans%mod;
}
};
方法二:
扫描线+线段树区间更新:时间O(N*logN)
但LeetCode上两个时间一样。。。24ms
class Solution {
public:
struct StateNode{
int y;
int tp;
int x1;
int x2;
StateNode():y(0),tp(0),x1(0),x2(0){}
void puts(int yy,int t,int a,int b){
y = yy; tp = t; x1 = a; x2 = b;
}
bool operator < (const StateNode& other) const{
if(this->y < other.y) return true;
return false;
}
};
struct TreeNode{
int type;
TreeNode* left;
TreeNode* right;
TreeNode(int tp):type(tp),left(NULL),right(NULL){}
};
long long getLenth(TreeNode* now,int L,int R,unordered_map<int,int>& pm){
// 有效区间都在叶子节点上
if(now->left == NULL && now->right == NULL){
if(now->type) return pm[R] - pm[L];
return 0;
}
int mid = (L+R)/2;
return getLenth(now->left,L,mid,pm) + getLenth(now->right,mid,R,pm);
}
void solve(TreeNode* now,int L,int R,int l,int r,int type){
// 当节点是叶节点,并且区间对的上,则更新type
if(now->left == NULL && now->right == NULL && L == l && R == r){
now->type += type;
return ;
}
if(now->left == NULL) now->left = new TreeNode(now->type);
if(now->right == NULL) now->right = new TreeNode(now->type);
int mid = (L+R)/2;
if(l < mid && r > mid){
solve(now->left,L,mid,l,mid,type);
solve(now->right,mid,R,mid,r,type);
}
if(r <= mid) solve(now->left,L,mid,l,r,type);
if(mid <= l) solve(now->right,mid,R,l,r,type);
}
int rectangleArea(vector<vector<int>>& rectangles) {
int N = rectangles.size();
vector<StateNode> sn(N*2);
map<int,int> mp;
for(int i=0;i<N;i++){
sn[i].puts(rectangles[i][1],1,rectangles[i][0],rectangles[i][2]);
sn[i+N].puts(rectangles[i][3],-1,rectangles[i][0],rectangles[i][2]);
mp[rectangles[i][0]] = mp[rectangles[i][2]] = 1;
}
sort(sn.begin(),sn.end());
int M = 0;
unordered_map<int,int> pm;
for(map<int,int>::iterator p=mp.begin();p!=mp.end();p++){
M++;
p->second = M;
pm[M] = p->first;
}
TreeNode* root = new TreeNode(0);
long long ans = 0;
long long last_y = 0;
for(int i=0;i<N+N;i++){
if(sn[i].y != last_y){
ans += (sn[i].y - last_y) * getLenth(root,1,M,pm);
last_y = sn[i].y;
}
solve(root,1,M,mp[sn[i].x1],mp[sn[i].x2],sn[i].tp);
}
const long long mod = 1000000007;
return ans%mod;
}
};