This is one of the very few notorious problems in LeetCode I dislike.
EPI code, but need to learn how to build datastructure to simplify the coding process.
#include <vector>
#include <iostream>
using namespace std;
struct Rectangle {
int left;
int right;
int height;
Rectangle(int l, int r, int h) : left(l), right(r), height(h) {}
};
typedef vector<Rectangle> Skyline;
void MergedInteractSkyline(Skyline* merged, Skyline* a, int* a_idx, Skyline* b, int* b_idx) {
if(a->right < b->right) {
if(a->height > b->height) {
if(b->right != a->right) {
merged->emplace_back(*a); *a_index++;
b->left = a->right;
} else *b_index++;
} else if (a->height == b->height) {
b->left = a->left; *a_index++;
} else { // a-height < b->height
if(a->left != b->left) {
merged->emplace_back(Rectangle(a->left, b->left, a->height));
}
*a_idx++;
}
} else { // if a->right > b->right
if(a->height >= b->height) {
*b_idx++;
} else {
if(b->left != a->left) {
merged->emplace_back(Rectangle(a->left, b->left, a->height));
}
a->left = b->right;
merged->emplace_back(*b);
*b_idx++;
}
}
}
Skyline mergeSkyline(Skyline* left_skyline, Skyline* right_skyline) {
int i = 0, j = 0;
Skyline merged;
while(i < left_skyline->size() && j < right_skyline->size()) {
if((*left_skyline)[i].right < (*right_skyline)[j].left) merged.push_back((*left_skyline)[i++]);
else if((*right_skyline)[j].right < (*left_skyline)[i].left) merged.push_back((*right_skyline)[j++]);
// left_skyline[i].right > right_skyline[j].left
else if((*left_skyline)[i].right > (*right_skyline)[j]) {
MergeInteractSkyline(&merged, &(*left_skyline)[i], &i, &(*right_skyline)[j], &j);
} else { // right_skyline[j].left > left_skyline[j].right;
MergeInteractSkyline(&merged, &(*right_skyline[j]), &j, &(*left_skyline[i]), &i);
}
}
// for the left-overs
merged.insert(merged.end(), left_skyline->begin() + i, left_skyline->end());
merged.insert(merged.end(), right_skyline->begin() + j, right_skyline->end());
}
Skyline getSkyline(const vector<Rectangle>& buildings, int left_endpoint, int right_endpoint) {
if(right_endpoint - left_endpoint <= 1) return {buildings.cbegin() + left_endpoint, buildings.cbegin() + right_endpoint};
int mid = left_endpoint + (right_endpoint - left_endpoint) / 2;
auto left_skyline = getSkyline(buildings, left_endpoint, mid);
auto right_skyline = getSkyline(buildings, mid + 1, right_endpoint);
return mergeSkyline(&left_skyline, &right_skyline);
}
Skyline getSkyline(vector< vector<int> >& buildings) {
vector<Rectange> rects;
for(int i = 0; i < buildings.size(); ++i) {
Rectangle rec(buildings[i][0], buildings[i][1], buildings[i][2]);
rects.push_back(rec);
}
Skyline result = getSkyline(rec, 0, rec.size());
return Skyline;
}
There is a heap-based solution. Willing to update it later.