马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
目录
一BFS办理FloodFill算法
1图像渲染
2岛屿数量
3岛屿的最大面积
4被围绕的区域
二BFS办理蛋源最短路径题目
1迷宫中离入口最近的出口
2最小基因厘革
3单词接龙
4为高尔夫比赛砍树
三BFS办理多源最短路径题目
1 01矩阵
2飞地的数量
3舆图中的最高点
4舆图分析
一BFS办理FloodFill算法
floodfill算法中文名:洪水灌溉:这类题目都是要来找出性子相同的联通块;办理好一道后,反面遇到类型的题目代码也是类似的!
1图像渲染
oj链接:图像渲染
解法:bfs
1.先把开始的坐标{sr,sc}放进队列中;
2.取出队头坐标{x,y},直接将它改成color(队列坐标都是合法的,待改的),再把它上下左右的坐标(等于image[sr][sc])放到队列中...
- //dfs
- class Solution
- {
- public:
- int target, newcolor, m, n;
- int dx[4] = {1, -1, 0, 0};
- int dy[4] = {0, 0, 1, -1};
- void dfs(vector<vector<int>> &image, int i, int j)
- {
- image[i][j] = newcolor;
- for (int a = 0; a < 4; a++)
- {
- int x = i + dx[a], y = j + dy[a];
- if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == target)
- {
- dfs(image, x, y);
- }
- }
- }
- vector<vector<int>> floodFill(vector<vector<int>> &image, int sr, int sc, int color)
- {
- if (image[sr][sc] == color)
- return image; // 特殊判断
- m = image.size(), n = image[0].size();
- target = image[sr][sc];
- newcolor = color;
- dfs(image, sr, sc);
- return image;
- }
- };
- //bfs
- class Solution
- {
- public:
- vector<vector<int>> floodFill(vector<vector<int>> &image, int sr, int sc, int color)
- {
- if (image[sr][sc] == color)
- return image; // 特殊判断
- // bfs前准备
- int dx[4] = {1, -1, 0, 0};
- int dy[4] = {0, 0, 1, -1};
- int m = image.size(), n = image[0].size();
- int target = image[sr][sc];
- // bfs主逻辑
- queue<pair<int, int>> qe;
- qe.push({sr, sc});
- while (qe.size())
- {
- int sz = qe.size();
- for (int i = 0; i < sz; i++)
- {
- auto &[a, b] = qe.front();
- qe.pop();
- if (image[a][b] == target)
- image[a][b] = color;
- for (int j = 0; j < 4; j++)
- {
- int x = a + dx[j], y = b + dy[j];
- if (x >= 0 && x < m && y >= 0 && y < n && image[x][y] == target)
- {
- qe.push({x, y});
- }
- }
- }
- }
- return image;
- }
- };
复制代码 2岛屿数量
oj链接:岛屿数量
解法:bfs
1. 两层for循环找‘1’&&该位置没被标志,将该坐标进队列,执行一次bfs;
2.bfs的主逻辑与上题类似:但在这里要注意:坐标进队列后要立刻马上举行标志!如果是取出节点后标志的话,会有重复节点进队列导致超时!!
- //dfs
- class Solution
- {
- public:
- bool vis[300][300] = {false};
- int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
- int m, n;
- void dfs(vector<vector<char>> &grid, int i, int j)
- {
- vis[i][j] = true;
- for (int a = 0; a < 4; a++)
- {
- int x = i + dx[a], y = j + dy[a];
- if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] == '1')
- {
- dfs(grid, x, y);
- }
- }
- }
- 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++;
- dfs(grid, i, j);
- }
- }
- }
- return ret;
- }
- };
- //bfs
- class Solution
- {
- public:
- bool vis[300][300] = {false};
- int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
- int m, n;
- queue<pair<int, int>> q;
- void bfs(vector<vector<char>> &grid, int i, int j)
- {
- //进队列后必须立刻进行标记!
- q.push({i, j});
- vis[i][j] = true;
- while (q.size())
- {
- auto [a, b] = q.front();
- q.pop();
- // vis[a][b]=true;节点会重复进队列,导致超时
- 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;
- }
- }
- }
- }
- 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;
- }
- };
复制代码 3岛屿的最大面积
oj链接:岛屿的最大面积
与上题思路类似:只不过我们要求的是最大面积,我们可以:举行dfs后把岛屿的面积带出来
- class Solution
- {
- public:
- int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, 1, -1};
- bool vis[50][50] = {false};
- int m, n;
- queue<pair<int, int>> q;
- void bfs(vector<vector<int>> &grid, int i, int j, int *area)
- {
- 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;
- (*area)++;
- }
- }
- }
- }
- 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])
- {
- int area = 1; // 从该位置进行bfs:找出该位置处岛屿的面积
- bfs(grid, i, j, &area);
- MaxArea = max(MaxArea, area);
- }
- }
- }
- return MaxArea;
- }
- };
复制代码 4被围绕的区域
oj链接:被围绕的区域
解法:bfs
此题在递归 搜刮与回溯算法题
- class Solution
- {
- public:
- bool vis[200][200];
- int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
- int m, n;
- queue<pair<int, int>> q;
- void bfs(vector<vector<char>> &board, int i, int j)
- {
- 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 && board[x][y] == 'O' && !vis[x][y])
- {
- q.push({x, y});
- vis[x][y] = true;
- }
- }
- }
- }
- void solve(vector<vector<char>> &board)
- {
- 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' && !vis[i][j])
- board[i][j] = 'X';
- }
- }
- }
- };
复制代码 二BFS办理蛋源最短路径题目
1迷宫中离入口最近的出口
oj链接:迷宫中离入口最近的出口
从开始粗来一次bfs遍历即可;如果进队列的坐标是出口,直接返回遍历的层数ret即可!
- class Solution
- {
- public:
- bool vis[100][100];
- int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
- int m, n;
- int nearestExit(vector<vector<char>> &maze, vector<int> &entrance)
- {
- m = maze.size(), n = maze[0].size();
- queue<pair<int, int>> q;
- int beginx = entrance[0], beginy = entrance[1];
- q.push({beginx, beginy});
- vis[beginx][beginy] = true;
- int ret = 0;
- while (q.size())
- {
- ret++; // 往外扩
- int sz = q.size();
- for (int i = 0; i < sz; i++)
- {
- 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 && maze[x][y] == '.' &&!vis[x][y])
- {
- if (x == 0 || x == m - 1 || y == 0 || y == n - 1)
- return ret; // 找到出口了,直接返回遍历的层数,即最短路径
- q.push({x, y});
- vis[x][y] = true;
- }
- }
- }
- }
- return -1;
- }
- };
复制代码 2最小基因厘革
oj链接:最小基因厘革
- class Solution
- {
- public:
- int minMutation(string startGene, string endGene, vector<string> &bank)
- {
- char arr[4] = {'A', 'G', 'C', 'T'};
- unordered_map<string, bool> vis;
- for (auto &s : bank)
- vis[s] = false;
- if(!vis.count(endGene)) return -1;// 不存在直接返回
- queue<string> q;
- q.push(startGene);
- vis[startGene] = true; // 有可能基因库也有这个,提前标记
- int ret = 0;
- while (q.size())
- {
- ret++;
- int sz = q.size();
- for (int i = 0; i < sz; i++)
- {
- string s = q.front();
- q.pop();
- for (int i = 0; i < 8; i++)
- {
- for (int j = 0; j < 4; j++)
- {
- string tmp = s;
- tmp[i] = arr[j]; // 这里就没必要判断tmp[i]是否与arr[j]相等:因为前面我们已经标记过了
- if (vis.count(tmp) && !vis[tmp])
- {
- if (tmp == endGene)
- return ret;
- q.push(tmp);
- vis[tmp] = true;
- }
- }
- }
- }
- }
- return -1;
- }
- };
复制代码 3单词接龙
oj链接:单词接龙
与上题思路类似
- class Solution
- {
- public:
- int ladderLength(string beginWord, string endWord, vector<string> &wordList)
- {
- string t = "qwertyuiopasdfghjklzxcvbnm";
- unordered_map<string, bool> vis;
- for (auto &word : wordList)
- vis[word] = false;
- if (!vis.count(endWord))
- return 0;
- int ans = 1;
- queue<string> qe;
- qe.push(beginWord);
- vis[beginWord] = true;
- while (qe.size())
- {
- ans++;
- int sz = qe.size();
- while (sz--)
- {
- string s = qe.front();
- qe.pop();
- for (int i = 0; i < s.size(); i++)
- {
- char ch = s[i];
- for (int j = 0; j < 26; j++)
- {
- s[i] = t[j];
- if (vis.count(s) && !vis[s])
- {
- if (s == endWord)
- return ans;
- qe.push(s);
- vis[s] = true;
- }
- }
- s[i] = ch;
- }
- }
- }
- return 0;
- }
- };
复制代码 4为高尔夫比赛砍树
oj链接:为高尔夫比赛砍树
注意:
不是说肯定要砍,当初做的时候就是看劈叉了~

- class Solution
- {
- public:
- typedef pair<int, int> PII;
- int n, m;
- int cutOffTree(vector<vector<int>> &forest)
- {
- // 先预处理砍树顺序
- vector<PII> trees;
- n = forest.size(), m = forest[0].size();
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < m; j++)
- {
- if (forest[i][j] > 1)
- trees.push_back({i, j});
- }
- }
- sort(trees.begin(), trees.end(), [&](const PII &p1, const PII &p2)
- { return forest[p1.first][p1.second] < forest[p2.first][p2.second]; });
- // 若干个迷宫问题的最小步数累加
- int dx = 0, dy = 0;
- int ret = 0;
- for (auto &[a, b] : trees)
- {
- int step = bfs(forest, dx, dy, a, b);
- if (step == -1)
- return -1;
- ret += step;
- dx = a, dy = b; // 更新位置
- }
- return ret;
- }
- int dx[4] = {0, 0, 1, -1};
- int dy[4] = {1, -1, 0, 0};
- int bfs(vector<vector<int>> &forest, int bx, int by, int ex, int ey)
- {
- if (bx == ex && by == ey)
- return 0;
- int step = 0;
- queue<PII> qe;
- bool vis[50][50] = {false};
- // 层序遍历主逻辑
- qe.push({bx, by});
- vis[bx][by] = true;
- while (qe.size())
- {
- step++;
- int size = qe.size();
- while (size--)
- {
- auto [a, b] = qe.front();
- qe.pop();
- for (int i = 0; i < 4; i++)
- {
- int x = dx[i] + a, y = dy[i] + b;
- if (x >= 0 && x < n && y >= 0 && y < m && !vis[x][y] && forest[x][y] != 0)
- {
- if (x == ex && y == ey)
- return step;
- vis[x][y] = true;
- qe.push({x, y});
- }
- }
- }
- }
- return -1;
- }
- };
复制代码 三BFS办理多源最短路径题目
1 01矩阵
oj链接:01 矩阵
解法:BFS + 正难则反
如果从1作为起点走到尽头0,那比及尽头时记载距离时就不知道是从哪一个1为起点的
以是我们从0为起点开始,走到不是0的位置就举行距离记载,同时把它
- class Solution
- {
- public:
- // bool vis[1000][1000];//开10000会溢出?
- int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
- int m, n;
- vector<vector<int>> updateMatrix(vector<vector<int>> &mat)
- {
- m = mat.size(), n = mat[0].size();
- vector<vector<int>> dist(m, vector<int>(n, -1));
- queue<pair<int, int>> q;
- for (int i = 0; i < m; i++)
- {
- for (int j = 0; j < n; j++)
- {
- if (mat[i][j] == 0)
- {
- dist[i][j] = 0;
- q.push({i, j});
- }
- }
- }
- // int step=0;
- while (q.size())
- {
- // step++;
- // int sz=q.size();
- // while(sz--)
- // {
- auto [a, b] = q.front();
- q.pop();
- for (int i = 0; i < 4; i++)
- {
- int x = dx[i] + a, y = dy[i] + b;
- // if(x>=0&&x<m&&y>=0&&y<n&&!vis[x][y])
- if (x >= 0 && x < m && y >= 0 && y < n && dist[x][y] == -1)
- {
- // dist[x][y]=cnt;
- // vis[x][y]=true;
- dist[x][y] = dist[a][b] + 1;
- q.push({x, y});
- }
- }
- // }
- }
- return dist;
- }
- };
复制代码 2飞地的数量
oj链接:飞地的数量
解法:dfs + 正难则反
a先把边界上的1进入队列并举行标志;
b举行dfs遍历(上下左右找合法坐标)只要它是1而且没被标志,就把它加入到队列中并举行标志;
c再次对grid举行遍历,只要坐标的值是1而且没别标志就代表它走不出边界,举行统计即可
- class Solution
- {
- public:
- bool vis[500][500];
- int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
- int m, n;
- int numEnclaves(vector<vector<int>> &grid)
- {
- m = grid.size(), n = grid[0].size();
- queue<pair<int, int>> q;
- // 边上1统计
- for (int i = 0; i < m; i++)
- {
- for (int j = 0; j < n; j++)
- {
- if (i == 0 || i == m - 1 || j == 0 || j == n - 1)
- {
- if (grid[i][j] == 1)
- {
- q.push({i, j});
- vis[i][j] = true;
- }
- }
- }
- }
- // bfs进行遍历
- while (q.size())
- {
- // int sz=q.size();
- // while(sz--)
- // {
- auto [a, b] = q.front();
- q.pop();
- for (int k = 0; k < 4; k++)
- {
- int x = dx[k] + a, y = dy[k] + b;
- if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] == 1)
- {
- q.push({x, y});
- vis[x][y] = true;
- }
- }
- // }
- }
- int ret = 0;
- for (int i = 0; i < m; i++)
- {
- for (int j = 0; j < n; j++)
- {
- if (!vis[i][j] && grid[i][j] == 1)
- ret++;
- }
- }
- return ret;
- }
- };
复制代码 3舆图中的最高点
oj链接:舆图中的最高点
解法:bfs
安排高度时,任意相邻的格子高度差至多为1,也就是既可以计划成0,也可以计划成1;
但题目要我们返回的是高度值最大的环境,以是我们贪心地把全部高度差都计划成1即可;
也就是从全部水域位置为起点来来依次bfs遍历即可完成使命~
- 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>> highestPeak(vector<vector<int>>& isWater)
- {
- queue<PII> qe;
- int n=isWater.size(),m=isWater[0].size();
- vector<vector<int>> hight(n,vector<int>(m,-1));
- for(int i=0;i<n;i++)
- {
- for(int j=0;j<m;j++)
- {
- if(isWater[i][j]==1)
- {
- qe.push({i,j});
- hight[i][j]=0;
- }
- }
- }
- while(qe.size())
- {
- int sz=qe.size();
- while(sz--)
- {
- auto[a,b]=qe.front();
- qe.pop();
- for(int i=0;i<4;i++)
- {
- int x=dx[i]+a,y=dy[i]+b;
- if(x>=0&&x<n&&y>=0&&y<m&&hight[x][y]==-1)
- {
- hight[x][y]=hight[a][b]+1;
- qe.push({x,y});
- }
- }
- }
- }
- return hight;
- }
- };
复制代码 4舆图分析
oj链接:舆图分析
与01矩阵的思路一样~
- //用dist数组
- class Solution
- {
- public:
- typedef pair<int, int> PII;
- int dx[4] = {0, 0, 1, -1};
- int dy[4] = {1, -1, 0, 0};
- int maxDistance(vector<vector<int>> &grid)
- {
- int n = grid.size(), m = grid[0].size();
- vector<vector<int>> dist(n, vector<int>(m, -1));
- queue<PII> qe;
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < m; j++)
- {
- if (grid[i][j] == 1)
- {
- qe.push({i, j});
- dist[i][j] = 0;
- }
- }
- }
- if (qe.size() == 0 || qe.size() == n * m)
- return -1; // 边界情况
- int ans = 0;
- while (qe.size())
- {
- auto [a, b] = qe.front();
- qe.pop();
- for (int i = 0; i < 4; i++)
- {
- int x = dx[i] + a, y = dy[i] + b;
- if (x >= 0 && x < n && y >= 0 && y < m && dist[x][y] == -1)
- {
- dist[x][y] = dist[a][b] + 1;
- qe.push({x, y});
- ans = max(ans, dist[x][y]);
- }
- }
- }
- return ans;
- }
- };
- //统计遍历层数
- class Solution
- {
- public:
- bool vis[100][100];
- int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
- int m, n, ret = -1;
- int maxDistance(vector<vector<int>> &grid)
- {
- m = grid.size(), n = grid[0].size();
- queue<pair<int, int>> q;
- for (int i = 0; i < m; i++)
- {
- for (int j = 0; j < n; j++)
- {
- if (grid[i][j] == 1)
- {
- q.push({i, j});
- vis[i][j] = true;
- }
- }
- }
- if (q.size() == 0 || q.size() == m * n)
- return ret;
- while (q.size())
- {
- ret++;
- int sz = q.size();
- while (sz--)
- {
- 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 && !vis[x][y])
- {
- q.push({x, y});
- vis[x][y] = true;
- }
- }
- }
- }
- return ret;
- }
- };
复制代码 以上便是全部内容,有题目欢迎在评论区指出,感谢观看!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |