1.图像渲染
我们这道题可以使用深搜来解决,利用一个队列遍历到与该点相连的所有像素相同的点,然后将其修改成指定的像素即可,直接上思路:
直接上代码:
class Solution {
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
int temp = image[sr][sc]; //保存当前的要修改的像素值
if(temp == color) return image; // 处理边界情况
int m = image.size(); // 横坐标
int n = image[0].size(); // 纵坐标
queue<pair<int,int>> q;
q.push({sr,sc});
while(q.size())
{
auto [a,b] = q.front();
q.pop();
image[a][b] = color;
for(int i = 0; i < 4; i++)
{
int x = a + dx[i];
int y = b + dy[i];
// 遍历上下左右四种情况,注意越界的问题
if(x >= 0 && x < m && y >= 0 && y < n && image[x][y] == temp)
{
q.push(make_pair(x,y));
}
}
}
return image;
}
};
2.岛屿数量
我们直接来看思路:
直接来写代码:
class Solution {
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
bool vis[301][301] = {false}; // 标记数据是否被使用
int m; // 横坐标
int 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] == false)
{
ret++;
bfs(grid,i,j);//把这块陆地为1的全部标记为true
}
}
}
return ret;
}
void bfs(vector<vector<char>>& grid, int i, int j)
{
queue<pair<int,int>> q;
q.push({i,j});
while(q.size())
{
auto [x,y] = q.front();
q.pop();
for(int k = 0; k < 4; k++)
{
int a = x + dx[k];
int b = y + dy[k];
if(a >= 0 && a < m && b >= 0 && b < n && grid[a][b] == '1' && vis[a][b] == false)
{
q.push({a,b});
vis[a][b] = true;
}
}
}
}
};
3.岛屿的最大面积
直接上思路:
直接上代码:
class Solution {
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
bool vis[51][51] = {false};
int m, n;
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
m = grid.size();
n = grid[0].size();
int maxarea = 0;
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
if(grid[i][j] == 1 && vis[i][j] == false)
{
maxarea = max(bfs(grid, i, j), maxarea);
}
}
}
return maxarea;
}
int bfs(vector<vector<int>>& grid, int i, int j)
{
queue<pair<int,int>> q;
q.push({i,j});
vis[i][j] = true;
int count = 1;
while(q.size())
{
auto [a, b] = q.front();
q.pop();
for(int k = 0; k < 4; k++)
{
int x = a + dx[k];
int y = b + dy[k];
if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && vis[x][y] == false)
{
q.push({x,y});
count++;
vis[x][y] = true;
}
}
}
return count;
}
};
4.被围绕的区域
首先我们来看看这道题目,我们可以肯定的是这个可以利用上面的图像渲染来做这道题目,但是呢?我们这道题目有点现在,在边界的情况下我们是不能修改的,但是也能做,我们第一遍bfs的时候,不修改里面的值,只遍历到那些边界的情况记录下来,第二次bfs的时候如果遇到上次边界的情况,我们就不修改,如果没有我们就修改,但是太麻烦了,我们有没有更简单的做法呢?正难则反,可以先利边缘相连的 'O' 区域做上标记,然后重新遍历矩阵,将没有标记过的 'O' 修改成 'X' 即可,直接上思路:
直接上代码:
class Solution {
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
// 由于在原数组上修改,所以不用标记
int m, n;
public:
void solve(vector<vector<char>>& board)
{
m = board.size(), n = board[0].size();
// 1. 先处理边界上的'O'联通块,全部修改成'.'
// 处理行
for (int j = 0; j < n; j++)
{
if (board[0][j] == 'O') bfs(board, 0, j);
if (board[m - 1][j] == 'O') bfs(board, m - 1, j);
}
for (int i = 0; i < m; i++)
{
if (board[i][0] == 'O') bfs(board, i, 0);
if (board[i][n - 1] == 'O') bfs(board, i, n - 1);
}
// 处理列
// 2. 还原
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (board[i][j] == 'O') board[i][j] = 'X';
else if (board[i][j] == '.') board[i][j] = 'O';
}
void bfs(vector<vector<char>>& board, int i, int j)
{
queue<pair<int, int>> q;
q.push({ i, j });
board[i][j] = '.';
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 && board[x][y] == 'O')
{
q.push({ x, y });
board[x][y] = '.';
}
}
}
}
};