LeetCode 218. The Skyline Problem

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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值