给你一个正整数 n,表示一个 n x n 的城市,同时给定一个二维数组 buildings,其中 buildings[i] = [x, y] 表示位于坐标 [x, y] 的一个 唯一建筑。
如果一个建筑在四个方向(左、右、上、下)中每个方向上都至少存在一个建筑,则称该建筑 被覆盖。
返回 被覆盖的建筑数量。
示例 1:

输入: n = 3, buildings = [[1,2],[2,2],[3,2],[2,1],[2,3]]
输出: 1
解释:
- 只有建筑
[2,2]被覆盖,因为它在每个方向上都至少存在一个建筑:- 上方 (
[1,2]) - 下方 (
[3,2]) - 左方 (
[2,1]) - 右方 (
[2,3])
- 上方 (
- 因此,被覆盖的建筑数量是 1。
示例 2:

输入: n = 3, buildings = [[1,1],[1,2],[2,1],[2,2]]
输出: 0
解释:
- 没有任何一个建筑在每个方向上都有至少一个建筑。
示例 3:

输入: n = 5, buildings = [[1,3],[3,2],[3,3],[3,5],[5,3]]
输出: 1
解释:
- 只有建筑
[3,3]被覆盖,因为它在每个方向上至少存在一个建筑:- 上方 (
[1,3]) - 下方 (
[5,3]) - 左方 (
[3,2]) - 右方 (
[3,5])
- 上方 (
- 因此,被覆盖的建筑数量是 1。
提示:
2 <= n <= 10^51 <= buildings.length <= 10^5buildings[i] = [x, y]1 <= x, y <= nbuildings中所有坐标均 唯一。
分析:先遍历 buildings 数组,统计每个横坐标 x 上, y 坐标的最大值和最小值,和每个纵坐标 y 上,x 坐标的最大值和最小值。接着重新遍历 buildings 数组,分别检查 buildlings[i] 的 x 是否处于对应 y 的最大值和最小值之间,和 y 是否处于对应 x 的最大值和最小值之间。如果两个条件都满足,说明 buildings[i] 被覆盖。
cpp
int countCoveredBuildings(int n, int** buildings, int buildingsSize, int* buildingsColSize) {
int ans=0;
int hor[n+5][3],ver[n+5][3];
for(int i=0;i<=n;++i)
hor[i][0]=ver[i][0]=0;
for(int i=0;i<buildingsSize;++i)
{
int x=buildings[i][0],y=buildings[i][1];
if(hor[x][0]==0)hor[x][1]=hor[x][2]=y,hor[x][0]=1;
else hor[x][1]=fmin(hor[x][1],y),hor[x][2]=fmax(hor[x][2],y);
if(ver[y][0]==0)ver[y][1]=ver[y][2]=x,ver[y][0]=1;
else ver[y][1]=fmin(ver[y][1],x),ver[y][2]=fmax(ver[y][2],x);
}
for(int i=0;i<buildingsSize;++i)
{
int x=buildings[i][0],y=buildings[i][1];
if((y>hor[x][1]&&y<hor[x][2])&&(x>ver[y][1]&&x<ver[y][2]))ans++;
// printf("ans=%d x=%d y=%d hor_min=%d hor_max=%d ver_min=%d ver_max=%d\n",ans,x,y,hor[x][1],hor[x][2],ver[y][1],ver[y][2]);
}
return ans;
}