leetcode 463. Island Perimeter

463. 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:
[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]

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

写程序之前可以想好测试用例,包括无效输入,正常输入,以及一些特殊的输入。无效输入包括空数组,正常输入为一些m x n 的二维数组, 特殊输入为1 x n 或 m x 1 一维数组,或以及1 x 1 的单个 数字。

思路:
首先读懂题意,题目需要我们计算水中陆地的周长。将问题抽象为矩阵后,我们只需要考虑矩阵中每个元素值为1元素的周围四个元素,不同情况将对陆地周长有不同的影响,下面分情况讨论:

  1. 周围四个元素都为1,则对周长无影响;
  2. 周围四个元素中有3个元素为1,则周长加1;
  3. 周围四个元素中有2个元素为1,则周长加2;
  4. 周围四个元素中有1个元素为1,则周长加3;
  5. 周围四个元素都不为1,则周长加4;

    总的来说,周长可由每个值为1的元素贡献叠加得到,每个元素的贡献值又由四个周围元素得到,假设四个元素中有x个值为0,则贡献为x,因此周长 =

    i=0j=0(4(xi1,j+xi+1,j+xi,j1+xi,j+1))

    注意,若元素在矩阵边界,则超出边界范围的元素值可假设为0,为了避免处理边界情况,可以在矩阵周围添加一圈元素值为0的元素。

最后分析一下算法的复杂度,该算法只需要遍历二维数组一次,因此时间复杂度为O(mn)。

有了完整的思路,我们就能写出程序了。

class Solution {
public:
    int islandPerimeter(vector<vector<int>>& grid) {
        if(grid.size() == 0) return 0;
        int res = 0;
        int row_size = grid.size();
        int col_size = grid[0].size();
        for(int row = 0;row < row_size;++row)
            for(int col = 0;col < col_size;++col)
                {   if(!grid[row][col]) 
                        continue;
                    int count_zero = 0;
                    count_zero += (row - 1 < 0)?1:(!grid[row - 1][col]);
                    count_zero += (row + 1 > row_size - 1)?1:(!grid[row + 1][col]);
                    count_zero += (col - 1 < 0)?1:(!grid[row][col - 1]);
                    count_zero += (col + 1 > col_size - 1)? 1:(!grid[row][col + 1]);
                    res += count_zero;
                }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值