简单的图遍历(可dfs,也可bfs),这里给出dfs。这里有个坑点:不能直接将个数传到下个栈帧然后用全局变量直接取值,虽然都会遍历到,但是计算的个数会被刷新变少,所以我这里直接让每个栈帧都分别返回它所找到1最后拼凑个数。
class Solution {
public:
int n, m;
int ne[4][2] = {{-1,0},{0,-1},{1,0},{0,1}}; //上左下右
bool st[55][55] = {0};
int dfs(vector<vector<int>> &grid, int x, int y) {
st[x][y] = true;
int cnt = 1;
for(int i = 0; i < 4; i++) {
int tx = x + ne[i][0];
int ty = y + ne[i][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
if(grid[tx][ty] && !st[tx][ty]) {
cnt += dfs(grid,tx,ty);
}
}
return cnt;
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
n = grid.size(), m = grid[0].size();
int res = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(grid[i][j] && !st[i][j])
res = max(res, dfs(grid,i,j));
return res;
}
};
- 二分图补充:A、B子集中的每个结点分别都互不相连。
- c o l o r color color :0表示未染色,1、2用来区分所染颜色。
- 由与题目给的图不一定是连通图,所以为了避免漏掉遍历的结点,故轮询一遍每个结点。
- 当相邻的点染为相同的颜色时,就说明染色失败,这个测试点就不是二分图,直接返回false即可。
- 3 − c 3-c 3−c 比较妙,当 c c c 为 1 时就返回 2 , c c c 为 2 时返回 1 ,刚好是相反的颜色。
class Solution {
public:
vector<int> color;
bool dfs(int u, int c, vector<vector<int>> &graph) {
color[u] = c;
for(const auto &v: graph[u]) {
if(!color[v]) {
if(!dfs(v,3-c,graph)) return false; //上个栈帧染色失败
} else if(color[v] == c) return false; //染相同颜色
}
return true;
}
bool isBipartite(vector<vector<int>>& graph) {
int n = graph.size();
color.resize(n);
for(int i = 0; i < n; i++) //轮询每个结点,以防非连通图
for(const auto &v: graph[i]) {
if(!color[v] && !dfs(v,1,graph)) return false;
}
return true;
}
};
广度优先(BFS)
- 使用 d f s dfs dfs 不好优化成记忆搜索,这里使用 B F S BFS BFS 会相对容易一些。
- 直接将所有 0 0 0 的点标记为访问过,并且都加入队列中。
- 然后开始 B F S BFS BFS ,那么理所当然的 0 0 0 的点都不会被再次加入队列。
- 由于 B F S BFS BFS 自带的最短步数特性,此时 1 1 1 的点等于上个点的步数+1一定是最短的。
- 然后再将 1 1 1 加入队列以此类推,直至所有点均访问完毕。
class Solution {
public:
int ne[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
typedef pair<int,int> PII;
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
int n = mat.size(), m = mat[0].size();
vector<vector<int>> dis(n, vector<int>(m,0));
vector<vector<bool>> st(n,vector<bool>(m,0));
queue<PII> que;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(mat[i][j] == 0) {
que.emplace(i,j);
st[i][j] = true;
}
while(que.size()) {
auto [x,y] = que.front(); que.pop();
for(int i = 0; i < 4; i++) {
int tx = x + ne[i][0];
int ty = y + ne[i][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= m || st[tx][ty]) continue;
dis[tx][ty] = dis[x][y] + 1;
st[tx][ty] = true;
que.emplace(tx,ty);
}
}
return dis;
}
};
这篇博客探讨了三种基于图遍历的算法在信息技术问题中的应用。首先,介绍了用于计算岛屿最大面积的深度优先搜索(DFS)策略,强调了在处理过程中避免错误计数的关键点。接着,讲解了如何通过DFS判断二分图,通过为节点染色来确保没有相邻节点拥有相同颜色。最后,展示了如何利用广度优先搜索(BFS)求解矩阵中元素间的最短距离,利用BFS的特性保证了找到的路径是最短的。这些算法在解决实际问题时具有重要的实践价值。
2120

被折叠的 条评论
为什么被折叠?



