463. 岛屿的周长

题目:

463. 岛屿的周长
在这里插入图片描述

题解:

1. 题解一:直接遍历

直接遍历数组,只要前面有相邻的方格,就-2。
因为方格A和方格B相邻,方格A,B需要分别减少一条边。

2. 题解二:深度优先搜索DFS(优选)

在这里插入图片描述

代码:

1. 代码一:直接遍历

/**
 * code463
 */
public class code463 {


    public static int islandPerimeter(int[][] grid) {
        // 重点关注前面遍历过得方格,如果之前有相邻方格,就-2;
        if(grid.length == 0)
        {
            return 0;
        }
        int length = 0;
        int m = grid.length;
        int n = grid[0].length;
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j] == 1)
                {
                    length += 4;
                    // 如果grid[i-1][j]不小于数组边界并且也等于1(岛)则边减2
                    if(i > 0 && grid[i - 1][j] == 1)
                    {
                        length -= 2;
                    }
                    // 如果grid[i][j-1]不小于数组边界并且也等于1(岛)则边减2
                    if(j > 0 && grid[i][j - 1] == 1)
                    {
                        length -= 2;
                    }
                }
            }
        }
        return length;
    }

    public static void main(String[] args) {
        int grid[][] = {
            {0, 1, 0, 0},
            {1, 1, 1, 0},
            {0, 1, 0, 0},
            {1, 1, 0, 0}
        };
        int res = islandPerimeter(grid);
        System.out.println(res);
    }
}

2. 代码二:深度优先搜索DFS(优选)

/**
 * code463
 */
public class code463 {

    public static int islandPerimeter(int[][] grid) {
        if(grid.length == 0)
        {
            return 0;
        }
        int m = grid.length;
        int n = grid[0].length;
        boolean visited[][] = new boolean[m][n];
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j] == 1)
                {
                    // 题目限制只有一个岛屿,计算一个岛屿即可,即找到一个岛屿后立刻返回即可
                    return dfs(i, j, m, n, grid, visited);
                }
            }
        }
        return 0;
    }

    public static int dfs(int i, int j, int m, int n, int grid[][], boolean visited[][])
    {
        // 从一个岛屿方格走向网格边界,周长加 1
        if(i < 0 || i >= m || j < 0 || j >= n)
        {
            return 1;
        }
        // 从一个岛屿方格走向水域方格,周长加 1
        if(grid[i][j] == 0)
        {
            return 1;
        }
        if(visited[i][j])
        {
            return 0;
        }
        //标记访问
        visited[i][j] = true;
        return dfs(i + 1, j, m, n, grid, visited) + dfs(i - 1, j, m, n, grid, visited) + dfs(i, j + 1, m, n, grid, visited) + dfs(i, j - 1, m, n, grid, visited);
    }

    public static void main(String[] args) {
        int grid[][] = {
            {0, 1, 0, 0},
            {1, 1, 1, 0},
            {0, 1, 0, 0},
            {1, 1, 0, 0}
        };
        int res = islandPerimeter(grid);
        System.out.println(res);
    }
}

参考:

  1. 图解:在 DFS 遍历过程中求周长(Java)
  2. 岛屿的周长
在 C 语言中,寻找岛屿周长通常涉及到矩阵操作和邻接矩阵的概念。岛屿是由连续的 '1'(代表陆地)包围的 '0'(代表水域)。一种常见的算法是使用四邻边(上、下、左、右)遍历矩阵,同时维护每个节点的访问状态。 下面是一个简单的伪代码示例: ```c void islandPerimeter(int maze[ROW][COL], int startRow, int startCol) { int visited[ROW][COL] = {0}; // 记录已访问的格子 visited[startRow][startCol] = 1; // 标记开始位置为已访问 // 初始化岛屿周长为0 int perimeter = 0; // 邻接方向数组 const int directions[] = {0, 1, 0, -1, 1, -1, -1, 1}; for (int i = 0; i < sizeof(directions)/sizeof(directions[0]); i++) { int newRow = startRow + directions[i]; int newCol = startCol + directions[(i+1)%8]; // 检查新位置是否越界,以及是否在水里或者之前已访问过 if (newRow >= 0 && newRow < ROW && newCol >= 0 && newCol < COL && maze[newRow][newCol] == 1 && !visited[newRow][newCol]) { perimeter++; // 统计边的数量 visited[newRow][newCol] = 1; } } perimeter += 4; // 四个边界也算作边,所以加到总周长上 printf("Island perimeter: %d\n", perimeter); } // 调用函数并传入网格和起始坐标 islandPerimeter(maze, 0, 0); ``` 在这个代码中,关键在于遍历相邻的四个方向,并检查新的位置是否符合条件(在矩阵范围内,且值为1且未访问过)。每次找到新边缘就增加周长,并标记该位置为已访问,避免重复计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dev_zyx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值