2025-10-17:统计被覆盖的建筑。用go语言,给定一个正整数 n,表示一个 n×n 的格子城市;同时给出一个数组 buil

举报
福大大架构师每日一题 发表于 2025/10/17 07:46:48 2025/10/17
【摘要】 2025-10-17:统计被覆盖的建筑。用go语言,给定一个正整数 n,表示一个 n×n 的格子城市;同时给出一个数组 buildings,每个元素 buildings[i] = [x,y] 表示在坐标 (x,y) 处有一座建筑,且这些坐标互不重复。如果某座建筑在它的上、下、左、右这四个方向上,沿各自的直线上至少还能找到另一座建筑,则称该建筑为“满足条件”。要求返回满足该条件的建筑总数。输入...

2025-10-17:统计被覆盖的建筑。用go语言,给定一个正整数 n,表示一个 n×n 的格子城市;同时给出一个数组 buildings,每个元素 buildings[i] = [x,y] 表示在坐标 (x,y) 处有一座建筑,且这些坐标互不重复。

如果某座建筑在它的上、下、左、右这四个方向上,沿各自的直线上至少还能找到另一座建筑,则称该建筑为“满足条件”。

要求返回满足该条件的建筑总数。

输入:正整数 n 和二维数组 buildings(坐标均为整数,通常落在 0 到 n−1 之间,且无重复)。

输出:一个整数,表示满足上述四个方向均有建筑这一条件的建筑数量。

2 <= n <= 100000。

1 <= buildings.length <= 100000。

buildings[i] = [x, y]。

1 <= x, y <= n。

buildings 中所有坐标均 唯一 。

输入: n = 3, buildings = [[1,1],[1,2],[2,1],[2,2]]。

输出: 0。

解释:

在这里插入图片描述

没有任何一个建筑在每个方向上都有至少一个建筑。

题目来自力扣3531。

解决步骤

1. 数据结构初始化

  • 创建两个数组 rowcol,长度均为 n+1(索引 1 到 n)。
  • row[y] 存储行 y 上所有建筑的 x 坐标的最小值和最大值。
  • col[x] 存储列 x 上所有建筑的 y 坐标的最小值和最大值。
  • 初始时,每个 row[y].mincol[x].min 设为最大整数(表示尚未找到建筑),每个 row[y].maxcol[x].max 设为最小整数(或 0,但后续会被覆盖)。

2. 收集每行和每列的信息

  • 遍历所有建筑 (x, y)
    • 更新 row[y].minmin(row[y].min, x)
    • 更新 row[y].maxmax(row[y].max, x)
    • 更新 col[x].minmin(col[x].min, y)
    • 更新 col[x].maxmax(col[x].max, y)
  • 这样,row[y] 记录了行 y 上最左和最右建筑的 x 坐标,col[x] 记录了列 x 上最上和最下建筑的 y 坐标。

3. 判断每个建筑是否满足条件

  • 再次遍历所有建筑 (x, y)
    • 检查行条件:row[y].min < x < row[y].max 是否成立。如果成立,说明在该行上,存在比 x 小的建筑(在左边)和比 x 大的建筑(在右边)。
    • 检查列条件:col[x].min < y < col[x].max 是否成立。如果成立,说明在该列上,存在比 y 小的建筑(在上边)和比 y 大的建筑(在下边)。
    • 如果行条件和列条件同时成立,则该建筑满足“四个方向均有建筑”的条件,计数加一。

4. 返回结果

  • 返回满足条件的建筑总数。

示例说明

对于输入 n=3, buildings=[[1,1],[1,2],[2,1],[2,2]]:

  • 行 1:建筑 x=1 和 x=2 → min=1, max=2。
  • 行 2:建筑 x=1 和 x=2 → min=1, max=2。
  • 列 1:建筑 y=1 和 y=2 → min=1, max=2。
  • 列 2:建筑 y=1 和 y=2 → min=1, max=2。

检查每个建筑:

  • (1,1):行 1 中 x=1 不是 min<x<max(x=1 等于 min),不满足行条件。
  • (1,2):行 2 中 x=1 等于 min,不满足行条件。
  • (2,1):行 1 中 x=2 等于 max,不满足行条件。
  • (2,2):行 2 中 x=2 等于 max,不满足行条件。

因此结果为 0。

复杂度分析

时间复杂度

  • 初始化 rowcol 数组:O(n)。
  • 遍历所有建筑更新 rowcol:O(k),其中 k = len(buildings)。
  • 再次遍历所有建筑检查条件:O(k)。
  • 总时间复杂度:O(n + k)。由于 k 最多为 100000,n 最多为 100000,这是线性的,可以接受。

空间复杂度

  • rowcol 数组各需要 O(n) 空间。
  • 总额外空间复杂度:O(n)。

总结
该算法通过记录每行和每列的最小/最大坐标,高效地判断每个建筑是否在四个方向上都有其他建筑,时间复杂度 O(n+k),空间复杂度 O(n)。

Go完整代码如下:

package main

import (
	"fmt"
	"math"
)

func countCoveredBuildings(n int, buildings [][]int) (ans int) {
	type pair struct{ min, max int }
	row := make([]pair, n+1)
	col := make([]pair, n+1)
	for i := 1; i <= n; i++ {
		row[i].min = math.MaxInt
		col[i].min = math.MaxInt
	}

	add := func(m []pair, x, y int) {
		m[y].min = min(m[y].min, x)
		m[y].max = max(m[y].max, x)
	}
	isInner := func(m []pair, x, y int) bool {
		return m[y].min < x && x < m[y].max
	}

	for _, p := range buildings {
		x, y := p[0], p[1]
		add(row, x, y) // x 加到 row[y] 中
		add(col, y, x) // y 加到 col[x] 中
	}

	for _, p := range buildings {
		x, y := p[0], p[1]
		if isInner(row, x, y) && isInner(col, y, x) {
			ans++
		}
	}
	return
}

func main() {
	n := 3
	buildings := [][]int{{1, 1}, {1, 2}, {2, 1}, {2, 2}}
	result := countCoveredBuildings(n, buildings)
	fmt.Println(result)
}

在这里插入图片描述

Python完整代码如下:

# -*-coding:utf-8-*-

def countCoveredBuildings(n, buildings):
    class Pair:
        def __init__(self):
            self.min = float('inf')
            self.max = float('-inf')
    
    row = [Pair() for _ in range(n+1)]
    col = [Pair() for _ in range(n+1)]
    
    def add(m, x, y):
        m[y].min = min(m[y].min, x)
        m[y].max = max(m[y].max, x)
    
    def is_inner(m, x, y):
        return m[y].min < x < m[y].max
    
    for p in buildings:
        x, y = p[0], p[1]
        add(row, x, y)  # x 加到 row[y] 中
        add(col, y, x)  # y 加到 col[x] 中
    
    ans = 0
    for p in buildings:
        x, y = p[0], p[1]
        if is_inner(row, x, y) and is_inner(col, y, x):
            ans += 1
    
    return ans

def main():
    n = 3
    buildings = [[1, 1], [1, 2], [2, 1], [2, 2]]
    result = countCoveredBuildings(n, buildings)
    print(result)

if __name__ == "__main__":
    main()

在这里插入图片描述

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。