【专题十五】BFS 解决 FloodFill
📝前言说明:
- 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,按专题划分
- 每题主要记录:(1)本人解法 + 本人屎山代码;(2)优质解法 + 优质代码;(3)精益求精,更好的解法和独特的思想(如果有的话)
- 文章中的理解仅为个人理解。如有错误,感谢纠错
🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C语言入门基础,python入门基础,C++学习笔记,Linux
🎀CSDN主页 愚润泽
你可以点击下方链接,进行该专题内不同子专题的学习
点击链接 | 开始学习 |
---|---|
双指针(1) | 双指针(2) |
双指针(3) | 双指针(4) |
滑动窗口(1) | 滑动窗口(2) |
滑动窗口(3) | 滑动窗口(4) |
二分查找(1) | 二分查找(2) |
前缀和(1) | 前缀和(2) |
前缀和(3) | 位运算(1) |
位运算(2) | 模拟算法 |
快速排序 | 归并排序 |
链表 | 哈希表 |
字符串 | 栈 |
队列 + 宽搜 | 优先级队列 |
BFS 解决 FloodFill | BFS 解决最短路径 |
多源 BFS | BFS 解决拓扑排序 |
题单汇总链接:点击 → 题单汇总(暂时未整理,因为还没刷完)
题目
- 733. 图像渲染
- 优质解
- 200. 岛屿数量
- 个人解
- 695. 岛屿的最大面积
- 个人解
- 130. 被围绕的区域
- 个人解
733. 图像渲染
题目链接:https://leetcode.cn/problems/flood-fill/description/
优质解
dfs
:深度优先,优先走完该路径所有元素- 是访问完 点1 以后 访问点1 周边的其中一个点2,然后再访问点 2周边的点3,访问点3周边的点4,直接把一条路走完。
bfs
:宽度优先,优先走完该层所有元素- 访问完 点1 以后访问 点1 周边的四个点(点2,点3,点4,点5)访问完以后,才去访问点2周边的点…
代码:
class Solution {
public:typedef pair<int, int> PII; // 表示二维下标int dx[4] = {0, 0 , 1, -1};int dy[4] = {1, -1 , 0, 0};vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {int base = image[sr][sc];if(base == color) return image;int m = image.size(), n = image[0].size();queue<PII> 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], y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && image[x][y] == base)q.push({x, y}); // 把要改的加入队列} }return image;}
};
时间复杂度:O(m∗n)O(m*n)O(m∗n)
空间复杂度:O(m∗n)O(m*n)O(m∗n),最坏情况下队列要存储全部像素
- 但是上面是出队时标记,其实不好,最好是入队时标记,请看下一题
200. 岛屿数量
题目链接:https://leetcode.cn/problems/number-of-islands/description/
个人解
屎山代码:
class Solution {
public:int dx[4] = {1, -1, 0, 0};int dy[4] = {0, 0, 1, -1};int m, n;void bfs(vector<vector<char>>& grid, int xi, int yi){queue<pair<int, int>> q;grid[xi][yi] = '0';q.push({xi, yi});while(q.size()){auto [a, b] = q.front();q.pop();// grid[a][b] = true; 不能这么写,出队时标记会导致重复入队for(int i = 0; i < 4; i++){int x = a + dx[i], y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1'){grid[x][y] = '0';q.push({x, y});}}}}int numIslands(vector<vector<char>>& grid) {m = grid.size(), n = grid[0].size();int ans = 0;for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(grid[i][j] == '1'){bfs(grid, i, j);ans++;}}}return ans;}
};
时间复杂度:O(m∗n)O(m*n)O(m∗n)
空间复杂度:O(min(m,n))O(min(m,n))O(min(m,n))
695. 岛屿的最大面积
题目链接:https://leetcode.cn/problems/max-area-of-island/description/
个人解
屎山代码:
class Solution {
public:int m, n;int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};int bfs(vector<vector<int>>& grid, int xi, int yi) // 返回该岛屿的面积{grid[xi][yi] = 0;int ret = 1;queue<pair<int, int>> q;q.push({xi, yi});while(q.size()){auto [a, b] = q.front();q.pop();for(int i = 0; i < 4; i++){int x = a + dx[i], y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1){ret++;grid[x][y] = 0;q.push({x, y}); // 入队时已经标记完了,入队只是为了探索该点周围的其他位置}}}return ret;}int maxAreaOfIsland(vector<vector<int>>& grid) {int ans = 0;m = grid.size(), n = grid[0].size();for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(grid[i][j])ans = max(ans, bfs(grid, i, j));}}return ans;}
};
时间复杂度:O(m∗n)O(m*n)O(m∗n)
空间复杂度:O(m∗n)O(m*n)O(m∗n)
130. 被围绕的区域
题目链接:https://leetcode.cn/problems/surrounded-regions/description/
个人解
屎山代码:
class Solution {
public:int m, n;int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};void bfs(vector<vector<char>>& board, int xi, int yi) // 把周围的'O'改成 'Z'{board[xi][yi] = 'Z';queue<pair<int, int>> q;q.push({xi, yi});while(q.size()){auto [a, b] = q.front();q.pop();for(int i = 0; i < 4; i++){int x = a + dx[i], y = b + dy[i];if(x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O'){board[x][y] = 'Z';q.push({x, y});}}}}void solve(vector<vector<char>>& board) {// 把所有连通的 'O' 改成 'X',但是周围的那一圈的不改// 我们可以先把周围的 'O'的连通块标记出来 m = board.size(), n = board[0].size(); 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);}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++){for(int j = 0; j < n; j++){if(board[i][j] == 'O')board[i][j] = 'X';else if(board[i][j] == 'Z')board[i][j] = 'O';}}}
};
时间复杂度:O(m∗n)O(m*n)O(m∗n)
空间复杂度:O(m∗n)O(m*n)O(m∗n)
🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!