深度优先搜索

Posted 浮云神码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度优先搜索相关的知识,希望对你有一定的参考价值。

    本次分享涉及图的连通分量,计算连通分量可以通过广度优先搜索和深度优先搜索实现。

    下面通过两种方式来实现,第一种是通过显示的栈来实现深度优先搜索,第二种是通过递归来实现深度优先搜索。

     本题的图是通过邻接矩阵来表示的。

import java.util.Stack;
/** * https://leetcode-cn.com/problems/number-of-provinces * 547. 省份数量 * 难度 中等 * 有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连, * 且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。 * * 省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。 * * 给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 * 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。 * * 返回矩阵中 省份 的数量。 * * 示例 1: * 输入:isConnected = [[1,1,0],[1,1,0],[0,0,1]] * 输出:2 * 示例 2: * 输入:isConnected = [[1,0,0],[0,1,0],[0,0,1]] * 输出:3 * * 提示: * * 1 <= n <= 200 * n == isConnected.length * n == isConnected[i].length * isConnected[i][j] 为 1 或 0 * isConnected[i][i] == 1 * isConnected[i][j] == isConnected[j][i] * * 来源:力扣(LeetCode) * 链接:https://leetcode-cn.com/problems/number-of-provinces */public class NumberOfProvinces { public int findCircleNum(int[][] isConnected) { int n = isConnected.length; // 顶点数为n, 创建长度为n的boolean数组存储是否已访问过对应的顶点 boolean[] visited = new boolean[n]; Stack<Integer> stack = new Stack<>(); int result = 0; for (int i = 0; i < n; i++) { // 若顶点未访问过, 则通过isConnected找到该顶点所有连通的顶点 // 将他们标记为已访问 if (!visited[i]) { visited[i] = true; result++; // 这里将该顶点所有的邻接顶点入栈 for (int j = 0; j < n; j++) { if (!visited[j] && isConnected[i][j] == 1) { visited[j] = true; stack.push(j); } } // 这里通过栈使用深度优先搜索, 不断的将邻接点入栈处理 while (!stack.isEmpty()) { Integer current = stack.pop(); for (int j = 0; j < n; j++) { if (!visited[j] && isConnected[current][j] == 1) { visited[j] = true; stack.push(j); } } } } } return result; }
/** * 递归版本 * @param isConnected * @return */ public int findCircleNum2(int[][] isConnected) { int n = isConnected.length; int result = 0; boolean[] visited = new boolean[n]; // 依次遍历所有顶点 for (int i = 0; i < n; i++) { // 一旦遇到未遍历过的顶点, 就意味着存在一个连通分量 if (!visited[i]) { // 之前没有被搜索到过, 连通分量+1 result++; visited[i] = true; // 这里进行递归调用 dfs(isConnected, visited, i); } } return result; }
public void dfs(int[][] isConnected, boolean[] visited, int current) { int n = isConnected.length; for (int i = 0; i < n; i++) { if (isConnected[current][i] == 1 && !visited[i]) { visited[i] = true; // 不断进行递归调用, 直到整个连通分量的所有顶点全部标记 dfs(isConnected, visited, i); } } }}


以上是关于深度优先搜索的主要内容,如果未能解决你的问题,请参考以下文章

深度优先搜索算法解释下?

深度优先搜索

搜索算法---深度优先搜索

图相关算法

深度优先搜索学习---(入门)

深度优先搜索