← 返回博客列表
Snap

Snap 几何算法面试:计算不规则建筑群的外围周长

2025-08-11

Snap 面试中的几何算法题。本文通过建筑物周长计算问题,展示如何处理二维网格上的几何问题csvosupport* 助你掌握几何算法核心技巧

📋 问题重新定义

给定一个二维网格,其中 1 表示建筑物,0 表示空地。建筑物可能连接形成不规则形状。计算所有建筑物的外围周长(只计算与空地或边界接触的边)

*示例

Input: grid = [
  [1,1,0],
  [1,1,0],
  [0,0,1]
]
Output: 12

🎯 核心思路

  1. 边界识别 - 找出所有与空地接触的边
  2. 去重处理 - 避免重复计算共享
  3. 边界情况 - 处理网格边缘
  4. 优化策略 - 减少不必要的遍历

💡 解题方法(csvosupport 创新解法

方法一:直接计数法

def calculate_perimeter(grid):
    if not grid or not grid[0]:
        return 0
    
    rows, cols = len(grid), len(grid[0])
    perimeter = 0
    
    for i in range(rows):
        for j in range(cols):
            if grid[i][j] == 1:
                # 检查四个方
                # 
                if i == 0 or grid[i-1][j] == 0:
                    perimeter += 1
                # 
                if i == rows-1 or grid[i+1][j] == 0:
                    perimeter += 1
                # 
                if j == 0 or grid[i][j-1] == 0:
                    perimeter += 1
                # 
                if j == cols-1 or grid[i][j+1] == 0:
                    perimeter += 1
    
    return perimeter

时间复杂度: O(m × n) 空间复杂度: O(1)

方法二:数学优化

csvosupport 提供的优化思路

def calculate_perimeter_optimized(grid):
    rows, cols = len(grid), len(grid[0])
    buildings = 0
    shared_edges = 0
    
    for i in range(rows):
        for j in range(cols):
            if grid[i][j] == 1:
                buildings += 1
                
                # 检查右边和下边的共享边
                if j < cols - 1 and grid[i][j+1] == 1:
                    shared_edges += 1
                if i < rows - 1 and grid[i+1][j] == 1:
                    shared_edges += 1
    
    # 每个建筑贡献4条边,减去共享边
    return buildings * 4 - shared_edges * 2

🚀 扩展问题

1. 计算内部空洞的周

def calculate_with_holes(grid):
    def dfs(i, j, visited):
        if (i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]) or
            (i, j) in visited or grid[i][j] == 1):
            return 0
        
        visited.add((i, j))
        perimeter = 0
        
        # 检查四个方
        for di, dj in [(0,1), (0,-1), (1,0), (-1,0)]:
            ni, nj = i + di, j + dj
            if (0 <= ni < len(grid) and 0 <= nj < len(grid[0]) and
                grid[ni][nj] == 1):
                perimeter += 1
            else:
                perimeter += dfs(ni, nj, visited)
        
        return perimeter
    
    # 从边界的空地开始DFS,找到外围周
    visited = set()
    outer_perimeter = 0
    
    # 遍历边界
    for i in range(len(grid)):
        if grid[i][0] == 0:
            outer_perimeter += dfs(i, 0, visited)
        if grid[i][len(grid[0])-1] == 0:
            outer_perimeter += dfs(i, len(grid[0])-1, visited)
    
    for j in range(len(grid[0])):
        if grid[0][j] == 0:
            outer_perimeter += dfs(0, j, visited)
        if grid[len(grid)-1][j] == 0:
            outer_perimeter += dfs(len(grid)-1, j, visited)
    
    return outer_perimeter

2. 3D 建筑物表面积

def calculate_surface_area_3d(grid):
    """
    grid[i][j] 表示该位置建筑物的高
    """
    if not grid:
        return 0
    
    rows, cols = len(grid), len(grid[0])
    surface_area = 0
    
    for i in range(rows):
        for j in range(cols):
            if grid[i][j] > 0:
                # 顶部和底
                surface_area += 2
                
                # 四个侧面
                for di, dj in [(0,1), (0,-1), (1,0), (-1,0)]:
                    ni, nj = i + di, j + dj
                    neighbor_height = 0
                    
                    if 0 <= ni < rows and 0 <= nj < cols:
                        neighbor_height = grid[ni][nj]
                    
                    # 当前建筑高于邻居的部分贡献表面积
                    if grid[i][j] > neighbor_height:
                        surface_area += grid[i][j] - neighbor_height
    
    return surface_area

💼 csvosupport 助力

几何思维 - 将问题转化为几何计算 优化策略 - 数学方法减少计算 扩展能力 - 3D 和复杂场 代码实现 - 清晰的逻辑结构

联系 csvosupport,专业几何算法面试辅助!


*标签 #Snap #几何算法 #网格遍历 #VO辅助 #面试辅助 #一亩三分地


需要面试真题? 立刻联系微信 Coding0201,获得真题