这种算法的思路是:要求 n 个矩形的轮廓,先将这 n 个矩形分成两个大小相等的部分,分别求其轮廓,然后再将这两
个轮廓合并。
规模为 1 的问题可以直接解决。具体来说,如果这个矩形的三元组表示为(L,H,R),那么其轮廓为(L,H,R,0)。
对于规模为 k 的问题,假设得到了两个规模为 k/2 的轮廓,分别为 A 和 B,我们如何得到合并后的轮廓 C?首先,容
易证明轮廓 C 的每一个横坐标,都来源于轮廓 A 和 B 的横坐标,而不会产生新的坐标值。因此,我们只需计算 A 和 B
中所有涉及到的横坐标在 C 中的高度。由于轮廓 C 中的横坐标值要求有序,我们可以仿照归并排序的方法,用两个指
针扫描轮廓 A 和 B。具体的方法是,设指针 i 指向轮廓 A 的当前横坐标,指针 j 指向轮廓 B 的当前横坐标。如果指针
i 指向的横坐标较小,那么将这一横坐标加入到 C 中,且在 C 中的高度为 A 中第 i 个横坐标对应的高度与 B 中第 j-1
个横坐标对应的高度的最大值,然后将指针 i 向后移一位;指针 j 指向的横坐标较小的情况则类似处理。如果两个指
针指向的横坐标相同,此时只需将这一横坐标加入到 C 中一次,且高度为两指针指向高度的最大值,然后将两指针同
时向后移一位。最后,需要扫描一遍轮廓 C,将相邻的高度相同的横坐标合并。
分析时间复杂度,设 T(n)表示解决规模为 n 的问题需要的时间,那么有。解此递归方程,得到 T(n)=O(nlogn)。
空间方面,由于递归的层数为 O(logn),每一层需要保存 O(n)的空间,所以总的空间复杂度为 O(nlogn)。
#define max(a,b) (a >= b? a : b) ;
const int BuildingNumber = 8;
typedef struct line
{
int start = -1;
int high = -1;
}*couple;
typedef struct triple
{
int left;
int right;
int high;
}*triplepointer;