Skip to content

Latest commit

 

History

History
 
 

850.Rectangle-Area-II

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

850.Rectangle-Area-II

解法1:暴力枚举网格

此题的思路是,将题目所给的所有矩形的坐标点都集中起来组成一个网格。具体来说,将所有的X坐标集中起来(要去除重复),将所有的Y坐标集中起来,然后将其两两配对组成一个二维的网络。注意,这样的网格点之间的实际距离并不是均匀的,但是没有关系。

我们再来遍历所有的矩形:在这个网络中找到每个矩形所框起来的范围(遵循左闭右开的原则),标记这个范围内的网格点为true,意味着这些网格点是落在被cover的面积里。遍历完所有的矩形后,所有标记为true的网格点都是要被算入面积的,而那些没有标记的说明不用被计算。

可以知道,凡是被cover的网格点(u,v),它所代表的面积就是(x[u+1]-x[u])*(y[v+1]-x[v])。我们只需要累加这些网格点所代表的面积即可。

解法2:二维差分数组

我们先来学习基本的二维差分数组。假设有很多小矩阵(左上角x0,y0, 右下角x1,y1),彼此之间可能互相覆盖。问整个盘面上每个格子是否有被任何矩阵覆盖。

对于一个矩阵,如果遍历所有内部的格子做标记,显然是效率很低的。我们很容易想到,是否能有类似一维扫描线算法(只记录两端的差分值)。这就是二维差分数组的应用。这里我们需要记录四个差分值:

diff[x0][y0]+=1;
diff[x0][y1+1]-=1;
diff[x1+1][y0]-=1;
diff[x1+1][y1+1]+=1;

这个差分数组diff[x][y]可以理解为整个盘面f[x][y]的二维梯度。f[x][y]表示了该点被多少个小矩形覆盖。

有了初始值,和差分数组diff[x][y],我们可以通过二维积分反推出f[x][y]

f[x][y] = f[x-1][y]+f[x][y-1]-f[x-1][y-1]+diff[x][y]

在本题中,我们需要将各个矩阵的边界(x值或y值)离散化为序号递增的网格(同解法1)。比如x=30可能对应着i=2,y=200可能对应着j=4.

假设一个矩形的四条边离散化后对应的是(i0,j0,i1,j1),需要注意到这四条行、列组成的矩形面积其实是比真实的矩形面积要大的(多算了一侧边界所占的“面积”)。所以我们约定靠右的列、靠上的行不算做该矩形的范围内。故差分数组的计算是:

diff[i0][j0]+=1;
diff[i0][j1]-=1;
diff[i1][j0]-=1;
diff[i1][j1]+=1;

我们利用以上的差分数组通过积分得到的f[i][j]表示的是: (i,j)所对应的(x0,y0)作为左下角、(i+1,j+1)所对应的(x1,y1)作为右上角的矩形被覆盖了几次。这个矩形的面积是(x1-x0)*(y1-y0).

我们需要累加所有f[i][j]>0的那些矩形的面积。

Leetcode Link