[LC]463. Island Perimeter

[LC]463. Island Perimeter_第1张图片[LC]463. Island Perimeter_第2张图片

这题是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;
    }

 

你可能感兴趣的:(Leetcode)