关于图的算法题总结
目录
解决方法
DFS
递归实现
非递归实现
BFS
递归实现
非递归实现
DFS+三色染色(可用于检查成环)
递归实现
非递归实现
多源BFS
并查集(可用于检查成环)
拓扑排序
Floyd最短路径
Dijkstra最短路径
最小生成树
Kruskal 算法
Prim 算法
解决方法
DFS
递归实现
200. 岛屿数量 - 力扣(LeetCode)
class Solution {
public:vector<int> dx{1, -1, 0, 0};vector<int> dy{0, 0, 1, -1};int cnt = 0;int m, n;void dfs(int x, int y, vector<vector<char>>& grid, vector<vector<int>>& visited) {if (x < 0 || y < 0 || x >= m || y >= n) return; // ✅ 用 m 和 n 分别判断if (grid[x][y] == '0' || visited[x][y]) return;visited[x][y] = 1;for (int i = 0; i < 4; i++)dfs(x + dx[i], y + dy[i], grid, visited);}int numIslands(vector<vector<char>>& grid) {m = grid.size(); // ✅ 行数if (m == 0) return 0;n = grid[0].size(); // ✅ 列数vector<vector<int>> vis(m, vector<int>(n, 0));for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == '1' && vis[i][j] == 0) {dfs(i, j, grid, vis);cnt++;}}}return cnt;}
};
非递归实现
易错点:在遍历二叉树的时候,应该先push入栈的是right右孩子,而不是left左孩子,因为栈是先进后出。
547. 省份数量 - 力扣(LeetCode)
class Solution {
public:void dfs(int start, vector<bool>& vis, vector<vector<int>>& isConnected){stack<int> st;st.push(start);while(!st.empty()){int root = st.top();st.pop();//遍历邻接矩阵找到root的邻居并放入栈for(int i = 0; i < isConnected.size(); i++){//如果是root邻居且没有被访问过if(isConnected[root][i]==1 && vis[i]==false){st.push(i);vis[i] = true;}}}}int findCircleNum(vector<vector<int>>& isConnected) {//基于DFS书写int ans = 0; //用于记录省份数量vector<bool> vis(isConnected.size(), false);//初始化访问数组for(int i = 0; i < isConnected.size(); i++){if(vis[i] == false){vis[i] = true;dfs(i, vis, isConnected);ans++;} //如果这个节点没有被访问过}return ans;}
};
BFS
递归实现
BFS 本身“队列式”的访问顺序决定了它天然不适合用纯粹的递归模拟;
非递归实现
103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode)
class Solution {
public:vector<vector<int>> zigzagLevelOrder(TreeNode* root) {//思路就是基于队列的BFSvector<vector<int>> res;queue<TreeNode*> qe;if(root!=nullptr) qe.push(root);while(!qe.empty()){vector<int> level;int n = qe.size();for(int i = 0; i<n; i++){TreeNode* now = qe.front();level.push_back(now->val);qe.pop();if(now->left!=nullptr) qe.push(now->left); if(now->right!=nullptr) qe.push(now->right);}//只不过最后push_back的时候做个判断如果是奇数层就reverse一下if