📝前言说明:
- 本专栏主要记录本人递归,搜索与回溯算法的学习以及LeetCode刷题记录,按专题划分
- 每题主要记录:(1)本人解法 + 本人屎山代码;(2)优质解法 + 优质代码;(3)精益求精,更好的解法和独特的思想(如果有的话)
- 文章中的理解仅为个人理解。如有错误,感谢纠错
🎬个人简介:努力学习ing
📋本专栏:C++刷题专栏
📋其他专栏:C语言入门基础,python入门基础,C++学习笔记,Linux
🎀CSDN主页 愚润泽
你可以点击下方链接,进行该专题内不同子专题的学习
点击链接 | 开始学习 |
---|---|
导论 | 递归 (一) 、递归 (二) |
二叉树的深搜 | 穷举 vs 暴搜 vs 深搜 vs 回溯 vs 剪枝 |
综合练习(一) | 综合练习(二) |
综合练习(三) | 综合练习(四) |
FloodFill(一) | FloodFill(二) |
记忆化搜索(一) | 记忆化搜索(二) |
题单汇总链接:点击 → 题单汇总
题目
- [FloodFill 算法介绍](#FloodFill 算法介绍)
- [733. 图像渲染](#733. 图像渲染)
- [200. 岛屿数量](#200. 岛屿数量)
- [695. 岛屿的最大面积](#695. 岛屿的最大面积)
FloodFill 算法介绍
- 找性质相同(比如同为负数...)的连通块,连通是指:上下左右直接相连的,斜的不算
- 解法:可用dfs / bfs来遍历(本专题讨论 dfs)
733. 图像渲染
题目链接:https://leetcode.cn/problems/flood-fill/description/
个人解
思路:
- 深度优先,往四个方向尝试
- 特别要注意无限递归问题
用时:10:00
屎山代码:
cpp
class Solution {
public:
int base;
int m, n;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
void dfs(vector<vector<int>>& image, int row, int col, int color)
{
for(int i = 0; i < 4; i++) // 遍历四个方向
{
int r = row + dx[i], l = col + dy[i];
if(r < m && r >= 0 && l < n && l >= 0 && image[r][l] == base)
{
image[r][l] = color;
dfs(image, r, l, color);
}
}
}
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color)
{
base = image[sr][sc]; // 初始像素的原始颜色
// 目标颜色和初始颜色相同直接返回(不然可能在几块区间反复调 dfs 无限递归)
if(base == color) return image;
m = image.size(); n = image[0].size();
image[sr][sc] = color;
dfs(image, sr, sc, color);
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/
个人解
思路:
- dfs不多说了
- 有一个很妙的地方,可以不用
check
数组:没走过一个为1
的地方就把它变成0
用时:16:00
屎山代码:
cpp
class Solution {
public:
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
int ans = 0;
int m, n;
void dfs(vector<vector<char>>& grid, int row, int col)
{
if(grid[row][col] == '1')
{
grid[row][col] = '0'; // 置为 0
for(int i = 0; i < 4; i++)
{
int r = row + dx[i], c = col + dy[i]; // 下一个位置
if(r < m && r >= 0 && c < n && c >= 0)
dfs(grid, r, c);
}
}
}
int numIslands(vector<vector<char>>& grid)
{
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] == '0')
continue;
else
{
dfs(grid, i, j); // 调用一次就会把一整块陆地找到
ans++; // 记录总 dfs 次数
}
}
}
return ans;
}
};
时间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)
空间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)
695. 岛屿的最大面积
题目链接:https://leetcode.cn/problems/max-area-of-island/description/
个人解
思路:
- 一样的方法,只是要注意,答案的更新放在dfs外面(用一个全局变量来记录每次dfs的面积,然后下一次dfs前重新置为0)
用时:6:00
屎山代码:
cpp
class Solution {
public:
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
int ans = 0;
int s = 0;
int m, n;
void dfs(vector<vector<int>>& grid, int row, int col) // s 记录面积
{
if(grid[row][col] == 1)
{
s++;
grid[row][col] = 0; // 置为 0
for(int i = 0; i < 4; i++)
{
int r = row + dx[i], c = col + dy[i]; // 下一个位置
if(r < m && r >= 0 && c < n && c >= 0)
dfs(grid, r, c);
}
}
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
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] == 0)
continue;
else
{
dfs(grid, i, j);
ans = max(ans, s);
s = 0;
}
}
}
return ans;
}
};
时间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)
空间复杂度: O ( m ∗ n ) O(m*n) O(m∗n)
🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!