这题是easy题,所以很easy。不过,还是有点可以取巧的地方。
最开始的最naive的做法就是走完整个方阵,走到每个方格的时候,首先设置基础周长为4,因为周围四个边。然后看上下左右四个方向有没有方格, 有的话就减一。然后得到的数字加到结果里即可。根据这个算法可以得到代码如下:
public int islandPerimeter(int[][] grid) {
int counter = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 0) continue;
int cellPeri = 4;
for (int k = -1; k <= 1; k++) {
if (k == 0) continue;
int horizontal = j + k;
int vertical = i + k;
if (horizontal >= 0 && horizontal < grid[0].length && grid[i][horizontal] == 1) cellPeri--;
if (vertical >= 0 && vertical < grid.length && grid[vertical][j] == 1) cellPeri--;
}
counter += cellPeri;
}
}
return counter;
}
当我跑完这段代码的时候,我发现它只能beat 35%的答案速度,然后我觉得大概是还有取巧的地方。于是,我查了一下别人的答案,发现还真的有。其实每走一个方格,你只需要看左边,和上面有没有方格就好,每有一个,就减2,道理很简单,如果方格a的左边有一个方格b,那么表示方格b的右边有方格a....好吧,这是废话,所以这个2,其实减的就是当前方格的左边那条边,和它左边方格的右边那条边。上下也是同一道理。然后,我们就可以得到下面这个代码。
public int islandPerimeter(int[][] grid) {
int counter = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 0) {
continue;
}
int cellPeri = 4;
int horizontal = j - 1;
int vertical = i - 1;
if (horizontal >= 0 && grid[i][horizontal] == 1) cellPeri -= 2;
if (vertical >= 0 && grid[vertical][j] == 1) cellPeri -= 2;
counter += cellPeri;
}
}
return counter;
}