题目地址:
https://www.lintcode.com/problem/island-perimeter/description
给定一个二维 0 − 1 0-1 0−1矩阵,其中只含一个 1 1 1连通块,此处连通是四连通。问这个连通块的周长。
思路是DFS,对 1 1 1连通块进行DFS,并且在DFS的时候看一下这个 1 1 1的四周有多少个 1 1 1,它对整个连通块周长的贡献就等于 4 4 4减去其四周 1 1 1的个数,进行累加即可。代码如下:
public class Solution {
// 存储最终答案
private int res = 0;
/**
* @param grid: a 2D array
* @return: the perimeter of the island
*/
public int islandPerimeter(int[][] grid) {
// Write your code here
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
dfs(i, j, grid);
// 由于连通块只有一个,所以一旦找到算出周长就直接返回之
return res;
}
}
}
return 0;
}
private void dfs(int x, int y, int[][] grid) {
// 为了节省空间,可以将这个位置标记为2,即表示已经访问过
grid[x][y] = 2;
int[] d = {1, 0, -1, 0, 1};
int countOf1 = 0;
for (int i = 0; i < 4; i++) {
int nextX = x + d[i], nextY = y + d[i + 1];
if (inBound(nextX, nextY, grid) && (grid[nextX][nextY] == 1 || grid[nextX][nextY] == 2)) {
countOf1++;
// 只有对未访问的邻接位置进行访问
if (grid[nextX][nextY] == 1) {
dfs(nextX, nextY, grid);
}
}
}
res += 4 - countOf1;
}
private boolean inBound(int x, int y, int[][] grid) {
return 0 <= x && x < grid.length && 0 <= y && y < grid[0].length;
}
}
时空复杂度 O ( m n ) O(mn) O(mn)。