求海岛周长

来源:互联网 发布:知世鼓励小狼 编辑:程序博客网 时间:2024/04/26 15:42

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
原创粉丝点击