LeetCode 463. Island Perimeter

You are given row x col grid representing a map where grid[i][j] = 1 represents land and grid[i][j] = 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", meaning the water inside 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 1:

Input: grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
Output: 16
Explanation: The perimeter is the 16 yellow stripes in the image above.

Example 2:

Input: grid = [[1]]
Output: 4

Example 3:

Input: grid = [[1,0]]
Output: 4

Constraints:

  • row == grid.length
  • col == grid[i].length
  • 1 <= row, col <= 100
  • grid[i][j] is 0 or 1.
  • There is exactly one island in grid.

这道题看起来真的很dfs……然而不会写dfs就看了答案,然后发现其实根本用不上dfs……

1. 非dfs做法:直接计算有多少个1,有n个1就一共有4 * n条边。如果这个格子有左右/上下邻居,那就得-2。只要一直往一个方向看邻居,就不会重复计算。

Runtime: 6 ms, faster than 99.61% of Java online submissions for Island Perimeter.

Memory Usage: 42.5 MB, less than 99.82% of Java online submissions for Island Perimeter.

class Solution {
    public int islandPerimeter(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        int result = 0;
        int rows = grid.length;
        int cols = grid[0].length;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (grid[i][j] == 1) {
                    result += 4;
                    if (j + 1 < cols && grid[i][j + 1] == 1) {
                        result -= 2;
                    }
                    if (i + 1 < rows && grid[i + 1][j] == 1) {
                        result -= 2;
                    }
                }
            }
        }
        return result;
    }
}

2. dfs解法

DFS的解法看完了只能说妙啊。从任意一个land出发进行dfs,dfs递归函数里传入grid, visited(其实不传visited,直接改变grid的内容也行),和两个index。主要的难点在于终止条件的判断:如果递归到了边界以外、或者是个water,那就相当于从原来的格子往外试图扩张失败,就需要周长+1;如果递归到了visited了,那就啥也不干;如果还是land的话,就上下左右递归调用dfs函数进行扩散,并mark为visited。

reference:Loading...

Runtime: 21 ms, faster than 14.16% of Java online submissions for Island Perimeter.

Memory Usage: 62.1 MB, less than 62.58% of Java online submissions for Island Perimeter.

class Solution {
    public int islandPerimeter(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        boolean[][] visited = new boolean[grid.length][grid[0].length];
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == 1) {
                    return dfs(grid, visited, i, j);
                }
            }
        }
        return 0;
    }
    
    private int dfs(int[][] grid, boolean[][] visited, int i, int j) {
        // if it's the boundary or water, return 1 as it has 1 edge that needs to be counted as perimeter
        if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) {
            return 1;
        }
        
        // if it's already visited, don't count
        if (visited[i][j]) {
            return 0;
        }
        
        // if it's land, dfs to its neighbors
        visited[i][j] = true;
        return dfs(grid, visited, i - 1, j) + dfs(grid, visited, i + 1, j) + dfs(grid, visited, i, j - 1) + dfs(grid, visited, i, j + 1);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值