求海岛周长

LeetCode原题:

Island Perimeter

Description:

You are given a map in form of a two-dimensional integer grid where 1 represents land and 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” (water inside that 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:

[[0,1,0,0],
 [1,1,1,0],
 [0,1,0,0],
 [1,1,0,0]]

Answer: 16

解法一:

遍历数组,当数组元素为1时,perimeter+=4,且如果此元素某侧(上、下、左、右)的元素为1,则perimeter-=2;
注:明显,这不是一种好的解法,编者提交后其运行时间只超过了30%的Java程序员

解法二:

同样遍历数组,当数组元素为1时,perimeter+=4,且如果此元素某侧(只判断左侧和下侧)的元素为1,则perimeter-=2;
注:提交后,LeetCode显示运行时间超过了70%的Java程序员,说明此解法是明显优于解法一的。

解法三:

在二的基础上,使用递归方法——即从第一个为1的元素开始遍历元素为1的部分。
这种解法的优点在于当表格很大且只有中间一部分是“海岛”时,速度会很快。
注:提交后,LeetCode显示运行时间超过了68%的Java程序员,貌似和解法二没有多大的区别,说明其运行速度受输入影响较大。

附代码:

//解法二
class Solution {
    public int islandPerimeter(int[][] grid) {
        int perimeter = 0;
        for(int i = 0 ; i < grid.length ; i++){
            for(int j = 0 ; j < grid[i].length ; j ++){
                if(grid[i][j] == 1){
                    perimeter += 4;
                    //对于船,只判断其左、下部是否为船
                    if(j > 0 && grid[i][j-1] == 1)
                        perimeter -= 2;
                    if(i < grid.length -1 && grid[i+1][j] == 1)
                        perimeter -= 2;
                }
            }
        }
        return perimeter;
    }
}
//解法三
class Solution {
    private int[][] travel;
    public int islandPerimeter(int[][] grid) {
        if(grid == null || grid.length <= 0 || grid[0].length <= 0)
            return 0;
        travel = new int[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 getPerimeter(grid, i, j);
                }
            }
        }
        return 0;
    }
    public int getPerimeter(int[][] grid, int pos1, int pos2){
        int minus = -4;//减去的部分
        int left = 0, right = 0, up = 0, down = 0;//标志左右是否为1
        if(pos1 < 0 || pos1 > travel.length-1 || 
                pos2 < 0 || pos2 > travel[0].length-1 ||
                travel[pos1][pos2] == 1)
            return 0;//如果已经探索过,则结束
        if(grid[pos1][pos2] == 1){
//          System.out.println("pos:"+pos1+" "+pos2);
            travel[pos1][pos2] = 1;
            travel[pos1][pos2] = 1;//之前未探索,则做个标记表示已经探索过
            if(pos1 > 0 && grid[pos1-1][pos2] == 1){
                up = 1;
                minus += 1;
            }
            if(pos1 < grid.length -1 && grid[pos1+1][pos2] == 1){
                down = 1;
                minus += 1;
            }
            if(pos2 > 0 && grid[pos1][pos2-1] == 1){
                left = 1;
                minus += 1;
            }
            if(pos2 < grid[0].length - 1 && grid[pos1][pos2+1] == 1){
                right = 1;
                minus += 1;
            }
//          System.out.println("minus:"+minus);
//          System.out.println("direction:"+up+" "+down+" "+left+" "+right);
            return -minus + up*getPerimeter(grid, pos1-1, pos2)
                           + down*getPerimeter(grid, pos1+1, pos2)
                           + left*getPerimeter(grid, pos1, pos2-1)
                           + right*getPerimeter(grid, pos1, pos2+1);
        }
        return 0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是用Java实现海岛计数的算法示例代码: ```java public class IslandCounter { public static int countIslands(int[][] grid) { int count = 0; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { if (grid[i][j] == 1) { count++; dfs(grid, i, j); } } } return count; } private static void dfs(int[][] grid, int i, int j) { if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) { return; } grid[i][j] = 0; dfs(grid, i - 1, j); dfs(grid, i + 1, j); dfs(grid, i, j - 1); dfs(grid, i, j + 1); } public static void main(String[] args) { int[][] grid = { {1, 1, 0, 0, 0}, {1, 1, 0, 0, 0}, {0, 0, 1, 0, 0}, {0, 0, 0, 1, 1} }; int count = countIslands(grid); System.out.println("海岛数量为:" + count); } } ``` 在上面的代码中,我们定义了一个countIslands()方法来计算二维数组中的海岛数量。该方法接受一个二维数组作为输入,其中1表示陆地,0表示海洋。我们使用两个for循环来遍历整个二维数组。对于每个值为1的格子,我们将其计数并使用深度优先搜索算法(dfs)来遍历所有与其相连的陆地,并将它们标记为0,表示已经被访问过。 在dfs()方法中,我们首先检查当前格子是否越界或者已经被访问过,如果是则直接返回。否则,我们将当前格子标记为0,并递归访问其上下左右四个相邻格子,继续执行相同的操作。 最后,我们返回计数器的值,即为海岛数量。 在示例代码中,我们定义了一个包含4个海岛的二维数组,并输出其海岛数量。输出结果为“海岛数量为:4”。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值