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

目录

岛屿数量(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;
 }
}
相关推荐
宸津-代码粉碎机4 小时前
OpenAI 连夜迎战 Grok Bot 和 Muse:AI 智能体从 “会聊天” 到 “能办事”,现在入场还来得及吗
java·大数据·人工智能·分布式·python
chenbingjie_c5 小时前
C++ 进阶核心知识点总结:模板、内存分区、new/delete、内存池
开发语言·c++
噢,我明白了6 小时前
java中唯一键和幂等键的应用
java·后端
程序猿乐锅6 小时前
【黑马点评 | 第八篇】Redisson分布式锁
java·数据库·spring boot·redis·分布式·spring·缓存
专注仿真6 小时前
ACM算法
算法·深度优先
考虑考虑6 小时前
synchronized字符串常量
java·后端·java ee
长谷深风1116 小时前
Tool与Skill:AI能力设计的分水岭
java·人工智能·ai·大模型·aiagent
m0_587383006 小时前
广州24小时自助健身房解决方案实战指南与系统部署要点
java·spring·小程序·架构·需求分析
Escalating_xu6 小时前
【C 语言】深入理解指针(1·下):指针运算、野指针、assert 与传址实战
java·c语言·开发语言
实心儿儿6 小时前
Qt — Qt 事件
开发语言·qt