LeetCode 218. The Skyline Problem
方法一:Line Sweep
几何类问题,可以用 Line Sweep nlogn 解决。维护一个active set,左边界进右边界出。排序时注意 corner cases:
1. 右边界和左边界x一样时,先处理左边界。
2. 多个左边界x一样时,高的先处理。
3. 多个右边界x一样时,矮的先处理。
sort的时候使用 e1.h*e1.type > e2.h*e2.type 判断,包括了上述三种情况,即 h*type 大的排在前面。
由于active set中可能有重复元素出现,用multiset erase的时候比较麻烦。因此用 {h, id} 这个pair来避免重复元素。
class Solution { public: struct edge { int x; int h; int id; int type; // left <- 1, right <- -1 }; vector<vector<int>> getSkyline(vector<vector<int>>& buildings) { vector<edge> vec; int id=0; for (auto b:buildings){ vec.push_back({b[0],b[2],id,1}); vec.push_back({b[1],b[2],id,-1}); ++id; } sort(vec.begin(),vec.end(),[](edge e1, edge e2){ if (e1.x==e2.x){ // contains all the corner cases return e1.h*e1.type > e2.h*e2.type; } return e1.x < e2.x; }); vector<vector<int>> res; set<pair<int,int>> active_set; // <h,id> for (edge e:vec){ if (e.type==1){ // left edge if (active_set.empty() || e.h > rbegin(active_set)->first){ res.push_back({e.x,e.h}); } active_set.insert({e.h,e.id}); }else{ // right edge active_set.erase({e.h,e.id}); if (active_set.empty()) res.push_back({e.x,0}); else if (e.h > rbegin(active_set)->first){ res.push_back({e.x,rbegin(active_set)->first}); } } } return res; } };
时间复杂度 O(nlogn)

浙公网安备 33010602011771号