Island Perimeter

本文介绍了一个算法问题:计算二维网格中岛屿的周长。通过遍历每个单元格并检查其相邻单元格的状态来确定周长。

You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water.

Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells).

The island doesn’t have “lakes” (water inside that isn’t connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don’t exceed 100. Determine the perimeter of the island.

Example:

Input:
[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]

Output: 16

Explanation: The perimeter is the 16 yellow stripes in the image below:

在这里插入图片描述

题目很好理解,让我们求岛的周长。其中,题目限定了只有一个岛,我们可以逐个grid遍历,对每个格子访问四周,若果是水,周长+1,若果格子是边界,那么周长也+1。

class Solution {
public:
    int islandPerimeter(vector<vector<int>>& grid) {
        
        int res=0;
        int m=grid.size(),n=grid[0].size();
        if (m==0) return res;
        for (int i=0;i<grid.size();i++)
        {
            for (int j=0;j<grid[0].size();j++)
            {
                if (grid[i][j]!=0)
                {
                    if (i==0||grid[i-1][j]==0) res++;
                    if (i==m-1||grid[i+1][j]==0) res++;
                    if (j==0||grid[i][j-1]==0) res++;
                    if (j==n-1||grid[i][j+1]==0) res++;
                }
            }
        }
        return res;
    }
    
    
};
<think>我们已知:岛屿的周长是陆地单元格与水域或网格边界相邻的边的数量总和。由于网格中只有一个岛屿(由水平或垂直相邻的陆地连接而成),我们可以遍历整个网格,对每个陆地格子,检查其四个方向(上下左右)是否为水域或者超出边界(即相当于水域),每有一个这样的边,周长就加1。 具体步骤: 1. 如果传入的网格为None,抛出TypeError异常。 2. 初始化周长为0。 3. 遍历网格的每一个格子(行和列)。 4. 如果当前格子是陆地(值为1),则检查它的四个相邻方向: 上方:如果当前格子是第一行,或者它上方的格子是水域(0),则周长+1。 下方:如果当前格子是最后一行,或者它下方的格子是水域(0),则周长+1。 左边:如果当前格子是第一列,或者它左边的格子是水域(0),则周长+1。 右边:如果当前格子是最后一列,或者它右边的格子是水域(0),则周长+1。 5. 返回总周长。 注意:题目保证网格中只有一个岛屿。 我们也可以换一种思路:每个陆地格子有4条边,但是相邻的两个陆地格子会共享一条边,这样这条边就不会被计入周长。因此,总周长 = 陆地格子数 * 4 - 相邻陆地格子之间的连接数 * 2(因为每个连接会使得两条边被抵消,即每条共享边会减少两个单位的周长)。但是,由于题目要求,我们使用第一种直观方法。 但是,根据引用[1]和[2]的提示,我们也可以使用DFS,但这里只有一个岛屿,且不需要担心多个岛屿,而且题目简单,直接遍历即可。 我们按照第一种直接遍历的方法实现。 示例网格: grid = [ [0,1,0,0], [1,1,1,0], [0,1,0,0], [1,1,0,0] ] 输出:16 实现代码: </think>### 岛屿周长算法实现 根据要求,我将实现一个名为 `island_perimeter` 的算法,该算法计算二维网格中唯一岛屿的周长。以下是根据引用资料的核心思路和完整实现: #### 算法思路 1. **问题本质**:计算岛屿(陆地单元格)与水域/网格边界相邻的边数总和 2. **关键特性**: - 每个陆地格子初始贡献4条边 - 每存在一个相邻陆地单元格(上下左右),减少2条边(双方各减1) 3. **优化方法**: - 只需遍历陆地单元格(值为1) - 检查四个方向的相邻关系: - 左邻:`(row, col-1)` - 上邻:`(row-1, col)` - 右邻:`(row, col+1)` - 下邻:`(row+1, col)` #### Python实现代码 ```python def island_perimeter(grid): """ 计算二维网格中岛屿的周长 参数: grid: List[List[int]] - 二维网格数组 (0表示水域,1表示陆地) 返回: int - 岛屿周长 异常: TypeError - 当输入grid为None时抛出 """ if grid is None: raise TypeError("输入网格不能为None") 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: # 陆地单元格 perimeter += 4 # 初始4条边 # 检查四个方向的相邻关系 if i > 0 and grid[i-1][j] == 1: # 上邻 perimeter -= 2 if j > 0 and grid[i][j-1] == 1: # 左邻 perimeter -= 2 return perimeter ``` #### 输入输出示例 ```python # 示例网格 grid = [ [0, 1, 0, 0], [1, 1, 1, 0], [0, 1, 0, 0], [1, 1, 0, 0] ] # 调用函数 print(island_perimeter(grid)) # 输出: 16 # None值测试 try: island_perimeter(None) except TypeError as e: print(e) # 输出: 输入网格不能为None ``` #### 算法复杂度 - **时间复杂度**:$O(m \times n)$(m行n列网格) - **空间复杂度**:$O(1)$(仅使用常量额外空间) 此实现满足: 1. 处理`None`输入抛出`TypeError` 2. 通过相邻检测优化计算(避免重复判断水域) 3. 符合岛屿周长定义:陆地-水域边界长度[^1][^2] 4. 高效处理大型网格(仅遍历陆地单元格)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值