题目
给定一个 row x col
的二维网格地图 grid
,其中:grid[i][j] = 1
表示陆地, grid[i][j] = 0
表示水域。
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1
的正方形。网格为长方形,且宽度和高度均不超过 100
。计算这个岛屿的周长。
示例 1:
输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
输出:16
解释:它的周长是上面图片中的 16 个黄色的边
示例 2:
输入:grid = [[1]]
输出:4
示例 3:
输入:grid = [[1,0]]
输出:4
提示:
row == grid.length
col == grid[i].length
1 <= row, col <= 100
-
解题方法
暴力破解
遍历每一个方块,如果遇到其上、下、左、右为地图边界或水域的情况,则周长加
1
。
时间复杂度O(mn)
,空间复杂度O(1)
。
C++代码:class Solution { public: int islandPerimeter(vector<vector<int>>& grid) { int row = grid.size(); int col = grid[0].size(); int result = 0; for(int i=0; i<row; i++) { for(int j=0; j<col; j++) { if(grid[i][j]) { if(!i || !grid[i-1][j]) result++; if(!j || !grid[i][j-1]) result++; if(j==col-1 || !grid[i][j+1]) result++; if(i==row-1 || !grid[i+1][j]) result++; } } } return result; } };
DFS
采用深度优先的方式搜索岛屿方块,返回周长值。搜索过程中需要记录上一个搜索的方块,避免重复搜索。终止条件为:
- 遇到边界或水域时返回
1
。 - 遇到已经遍历过的方块时返回
0
。
- 遇到边界或水域时返回
时间复杂度O(mn)
(最差情况),空间复杂度O(mn)
(递归栈)。
C++代码:
class Solution {
private:
int row, col;
public:
int dfs(vector<vector<int>>& grid, int x, int y, int indirect) {
if(x<0 || y<0 || x>=row || y>=col || !grid[x][y]) return 1;
if(grid[x][y]==2) return 0;
grid[x][y]=2;
int result = 0;
if(!(indirect&(1<<0))) result += dfs(grid, x-1, y, (1<<3));
if(!(indirect&(1<<1))) result += dfs(grid, x, y-1, (1<<2));
if(!(indirect&(1<<2))) result += dfs(grid, x, y+1, (1<<1));
if(!(indirect&(1<<3))) result += dfs(grid, x+1, y, (1<<0));
return result;
}
int islandPerimeter(vector<vector<int>>& grid) {
row = grid.size();
col = grid[0].size();
int x=0, y=0;
while(!grid[x][y]) {
y++;
if(y==col) {
x++;
y=0;
}
}
return dfs(grid, x, y, 0);
}
};