【优选算法】(第四十篇)

目录

岛屿数量(medium)

题目解析

讲解算法原理

编写代码

岛屿的最⼤⾯积(medium)

题目解析

讲解算法原理

编写代码


岛屿数量(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给你⼀个由'1'(陆地)和'0'(⽔)组成的的⼆维⽹格,请你计算⽹格中岛屿的数量。岛屿总是被⽔包围,并且每座岛屿只能由⽔平⽅向和/或竖直⽅向上相邻的陆地连接形成。此外,你可以假设该⽹格的四条边均被⽔包围。

⽰例1:

输⼊:grid=[

"1","1","1","1","0",

"1","1","0","1","0",

"1","1","0","0","0",

"0","0","0","0","0"

]

输出:1

⽰例2:

输⼊:grid=[

"1","1","0","0","0",

"1","1","0","0","0",

"0","0","1","0","0",

"0","0","0","1","1"

]

输出:3

提⽰:

m == grid.length

n == gridi.length

1 <= m, n <= 300

gridij 的值为'0'或'1'

讲解算法原理

算法思路:

遍历整个矩阵,每次找到「⼀块陆地」的时候:

• 说明找到「⼀个岛屿」,记录到最终结果 ret ⾥⾯;• 并且将这个陆地相连的所有陆地,也就是这块「岛屿」,全部「变成海洋」。这样的话,我们下次

遍历到这块岛屿的时候,它「已经是海洋」了,不会影响最终结果。• 其中「变成海洋」的操作,可以利⽤「深搜」和「宽搜」解决,其实就是733.图像渲染这道题~

这样,当我们,遍历完全部的矩阵的时候, ret 存的就是最终结果。

编写代码

c++算法代码:

cpp 复制代码
class Solution
{
 int dx[4] = {1, -1, 0, 0};
 int dy[4] = {0, 0, 1, -1};
 bool vis[301][301];
 int m, n;
public:
 int numIslands(vector<vector<char>>& grid) 
 {
 m = grid.size(), n = grid[0].size();
 int ret = 0;
 for(int i = 0; i < m; i++)
 {
 for(int j = 0; j < n; j++)
 {
 if(grid[i][j] == '1' && !vis[i][j])
 {
 ret++;
 bfs(grid, i, j); // 把这块陆地全部标记⼀下
 }
 }
 }
 return ret;
 }
 void bfs(vector<vector<char>>& grid, int i, int j)
 {
 queue<pair<int, int>> q;
 q.push({i, j});
 vis[i][j] = true;
 while(q.size())
 {
 auto [a, b] = q.front();
 q.pop();
 for(int k = 0; k < 4; k++)
 {
 int x = a + dx[k], y = b + dy[k];
 if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1' && 
!vis[x][y])
 {
 q.push({x, y});
 vis[x][y] = true;
 }
 }
 }
 }
};

java算法代码:

java 复制代码
class Solution
{
 int[] dx = {0, 0, -1, 1};
 int[] dy = {1, -1, 0, 0};
 boolean[][] vis = new boolean[301][301];
 int m, n;
 public int numIslands(char[][] grid) 
 {
 m = grid.length; n = grid[0].length;
 int ret = 0;
 for(int i = 0; i < m; i++)
 {
 for(int j = 0; j < n; j++)
 {
 if(grid[i][j] == '1' && !vis[i][j])
 {
 ret++;
 bfs(grid, i, j);
 }
 }
 }
 return ret;
 }
 public void bfs(char[][] grid, int i, int j)
 {
 Queue<int[]> q = new LinkedList<>();
 q.add(new int[]{i, j});
 vis[i][j] = true;
 while(!q.isEmpty())
 {
 int[] t = q.poll();
 int a = t[0], b = t[1];
 for(int k = 0; k < 4; k++)
 {
 int x = a + dx[k], y = b + dy[k];
 if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1' && 
!vis[x][y])
 {
 q.add(new int[]{x, y});
 vis[x][y] = true;
 }
 }
 }
 }
}

岛屿的最⼤⾯积(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给你⼀个⼤⼩为mxn的⼆进制矩阵grid。岛屿是由⼀些相邻的1(代表⼟地)构成的组合,这⾥的「相邻」要求两个1必须在⽔平或者竖直的

四个⽅向上相邻。你可以假设grid的四个边缘都被0(代表⽔)包围着。岛屿的⾯积是岛上值为1的单元格的数⽬。

计算并返回grid中最⼤的岛屿⾯积。如果没有岛屿,则返回⾯积为0。

⽰例1:

输⼊:

grid=\[0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,

0,1,0,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,

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

输出:6解释:

答案不应该是11,因为岛屿只能包含⽔平或垂直这四个⽅向上的1。

⽰例2:输⼊:

grid=\[0,0,0,0,0,0,0,0]

输出:0

提⽰:

m==grid.length

n==gridi.length

1<=m,n<=50

gridij为0或1

讲解算法原理

算法思路:

• 遍历整个矩阵,每当遇到⼀块⼟地的时候,就⽤「深搜」或者「宽搜」将与这块⼟地相连的「整个

岛屿」的⾯积计算出来。

• 然后在搜索得到的「所有的岛屿⾯积」求⼀个「最⼤值」即可。• 在搜索过程中,为了「防⽌搜到重复的⼟地」:

◦ 可以开⼀个同等规模的「布尔数组」,标记⼀下这个位置是否已经被访问过;◦ 也可以将原始矩阵的 1 修改成 0 ,但是这样操作会修改原始矩阵。

编写代码

c++算法代码:

cpp 复制代码
class Solution
{
 int dx[4] = {0, 0, 1, -1};
 int dy[4] = {1, -1, 0, 0};
 bool vis[51][51];
 int m, n;
public:
 int maxAreaOfIsland(vector<vector<int>>& grid) 
 {
 m = grid.size(), n = grid[0].size();
 int ret = 0;
 for(int i = 0; i < m; i++)
 {
 for(int j = 0; j < n; j++)
 {
 if(grid[i][j] == 1 && !vis[i][j])
 {
 ret = max(ret, bfs(grid, i, j));
 }
 }
 }
 return ret;
 }
 int bfs(vector<vector<int>>& grid, int i, int j)
 {
 int count = 0;
 queue<pair<int, int>> q;
 q.push({i, j});
 vis[i][j] = true;
 count++;
 while(q.size())
 {
 auto [a, b] = q.front();
 q.pop();
 for(int k = 0; k < 4; k++)
 {
 int x = a + dx[k], y = b + dy[k];
 if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && 
!vis[x][y])
 {
 q.push({x, y});
 vis[x][y] = true;
 count++;
 }
 }
 }
 return count;
 }
};

java算法代码:

java 复制代码
class Solution
{
 int[] dx = {0, 0, 1, -1};
 int[] dy = {1, -1, 0, 0};
 boolean[][] vis = new boolean[51][51];
 int m, n;
 public int maxAreaOfIsland(int[][] grid) 
 {
 m = grid.length; n = grid[0].length;
 int ret = 0;
 for(int i = 0; i < m; i++)
 {
 for(int j = 0; j < n; j++)
 {
 if(grid[i][j] == 1 && !vis[i][j])
 {
 ret = Math.max(ret, bfs(grid, i, j));
 }
 }
 }
 return ret;
 }
 public int bfs(int[][] grid, int i, int j)
 {
 int count = 0;
 Queue<int[]> q = new LinkedList<>();
 q.add(new int[]{i, j});
 vis[i][j] = true;
 count++;
 while(!q.isEmpty())
 {
 int[] t = q.poll();
 int a = t[0], b = t[1];
 for(int k = 0; k < 4; k++)
 {
 int x = a + dx[k], y = b + dy[k];
 if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && 
!vis[x][y])
 {
 q.offer(new int[]{x, y});
 vis[x][y] = true;
 count++;
 }
 }
 }
 return count;
 }
}
相关推荐
青少儿编程课堂20 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会C/C++考级:拓扑排序课程表排课解析
c++·python·算法·bfs·信息学竞赛
const_qiu20 小时前
第三章 04:3.6 基础调用链的构建
开发语言·python
一条泥憨鱼20 小时前
AI Agent 安全实践:从 MCP 工具调用到 Java 权限校验
java·人工智能·安全
向上的车轮20 小时前
Python 大数据处理不慢:Polars + DuckDB + Arrow 实战指南
开发语言·python
Nebula_g20 小时前
云禾外卖补充—项目整体后端运行逻辑-对流程的更深层次理解
java·开发语言·网络·数据库·状态模式·javase
萧瑟余晖20 小时前
Spring Security 6.x新特性与架构演进详解
java·spring·架构
\光辉岁月/20 小时前
1.Object类
java·面向对象·object类
暖焰核心20 小时前
二叉搜索树——从插入查到key-value改写
c++
鸽鸽程序猿20 小时前
【项目】【在线判题系统】公共功能
java·spring boot·maven
一只笨菜鸟21 小时前
IDEA如何让多个项目同时显示
java·ide·intellij-idea