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

目录

岛屿数量(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 == grid[i].length

1 <= m, n <= 300

grid[i][j] 的值为'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==grid[i].length

1<=m,n<=50

grid[i][j]为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;
 }
}
相关推荐
Tiandaren25 分钟前
Selenium 4 教程:自动化 WebDriver 管理与 Cookie 提取 || 用于解决chromedriver版本不匹配问题
selenium·测试工具·算法·自动化
胚芽鞘68133 分钟前
关于java项目中maven的理解
java·数据库·maven
nbsaas-boot1 小时前
Java 正则表达式白皮书:语法详解、工程实践与常用表达式库
开发语言·python·mysql
岁忧1 小时前
(LeetCode 面试经典 150 题 ) 11. 盛最多水的容器 (贪心+双指针)
java·c++·算法·leetcode·面试·go
chao_7891 小时前
二分查找篇——搜索旋转排序数组【LeetCode】两次二分查找
开发语言·数据结构·python·算法·leetcode
CJi0NG2 小时前
【自用】JavaSE--算法、正则表达式、异常
java
风无雨2 小时前
GO 启动 简单服务
开发语言·后端·golang
Hellyc2 小时前
用户查询优惠券之缓存击穿
java·redis·缓存
斯普信专业组2 小时前
Go语言包管理完全指南:从基础到最佳实践
开发语言·后端·golang
今天又在摸鱼2 小时前
Maven
java·maven