目录
岛屿数量(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;
}
}