class Solution {
public int numIslands(char[][] grid) {
int rows = grid.length;
int clolumns = grid[0].length;
if (grid == null || rows == 0) {
return 0;
}
int numIsLands = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < clolumns; j++) {
if (grid[i][j] == '1') {
numIsLands++;
dfs(grid, i, j);
}
}
}
return numIsLands;
}
private void dfs(char[][] grid, int row, int clolumn) {
int rows = grid.length;
int clolumns = grid[0].length;
if (row < 0 || clolumn < 0 || row >= rows || clolumn >= clolumns || grid[row][clolumn] == '0') {
return;
}
grid[row][clolumn] = '0';
dfs(grid, row - 1, clolumn);
dfs(grid, row + 1, clolumn);
dfs(grid, row, clolumn - 1);
dfs(grid, row, clolumn + 1);
}
}
class Solution {
int m;
int n;
public void solve(char[][] board) {
// 获取二维字符数组的行数
m = board.length;
// 如果二维字符数组为空,直接返回
if (m == 0) {
return;
}
// 获取二维字符数组的列数
n = board[0].length;
// 遍历第一列和最后一列,对与边界相连的'O'进行深度优先搜索并标记为'A'
for (int i = 0; i < m; i++) {
dfs(board, i, 0);
dfs(board, i, n - 1);
}
// 遍历第一行和最后一行的中间部分,对与边界相连的'O'进行深度优先搜索并标记为'A'
for (int i = 0; i < n; i++) {
dfs(board, 0, i);
dfs(board, m - 1, i);
}
// 再次遍历整个二维字符数组
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// 如果当前位置为'A',说明是与边界相连的'O',恢复为'O'
if (board[i][j] == 'A') {
board[i][j] = 'O';
} else {
// 如果当前位置为'O'且不是与边界相连的,替换为'X'
board[i][j] = 'X';
}
}
}
}
private void dfs(char[][] board, int x, int y) {
// 如果坐标越界或者当前位置不是'O',直接返回
if (x < 0 || x >= m || y < 0 || y >= n || board[x][y]!= 'O') {
return;
}
// 将当前位置标记为'A'
board[x][y] = 'A';
// 对上下左右四个方向进行深度优先搜索
dfs(board, x + 1, y);
dfs(board, x - 1, y);
dfs(board, x, y + 1);
dfs(board, x, y - 1);
}
}
class Solution {
// 存储已访问节点及其对应的克隆节点
private HashMap<Node, Node> visited = new HashMap<>();
public Node cloneGraph(Node node) {
// 如果输入节点为空,直接返回空
if (node == null) {
return node;
}
// 如果该节点已经被访问过了,则直接从哈希表中取出对应的克隆节点返回
if (visited.containsKey(node)) {
return visited.get(node);
}
// 创建一个新的节点,值与输入节点相同,邻居列表初始为空
Node cloneNode = new Node(node.val, new ArrayList());
// 将输入节点和克隆节点放入哈希表中
visited.put(node, cloneNode);
// 遍历输入节点的邻居列表
for (Node neighbor : node.neighbors) {
// 递归地克隆邻居节点,并将克隆后的邻居节点添加到克隆节点的邻居列表中
cloneNode.neighbors.add(cloneGraph(neighbor));
}
// 返回克隆后的节点
return cloneNode;
}
}
import java.util.*;
// 定义 Solution 类
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
// 1. 创建一个图,使用嵌套 HashMap 存储每对变量之间的关系
Map<String, Map<String, Double>> graph = new HashMap<>();
int n = equations.size();
// 2. 构建图
for (int i = 0; i < n; i++) {
String u = equations.get(i).get(0); // 第一个变量
String v = equations.get(i).get(1); // 第二个变量
double weight = values[i]; // 变量之间的值
// 添加边及其反向边
graph.putIfAbsent(u, new HashMap<>()); // 如果 u 不在图中,初始化它
graph.putIfAbsent(v, new HashMap<>()); // 如果 v 不在图中,初始化它
graph.get(u).put(v, weight); // u 到 v 的边
graph.get(v).put(u, 1.0 / weight); // v 到 u 的边
}
// 3. 准备结果数组,默认为 -1.0(表示无解)
int m = queries.size();
double[] results = new double[m];
Arrays.fill(results, -1.0);
// 4. 对每个查询进行 BFS
for (int i = 0; i < m; i++) {
String start = queries.get(i).get(0); // 查询的起始变量
String target = queries.get(i).get(1); // 查询的目标变量
// 检查起始变量和目标变量是否存在于图中
if (!graph.containsKey(start) || !graph.containsKey(target)) {
continue; // 如果任一变量不存在,跳过此查询
}
// 处理起始变量与目标变量相同的情况
if (start.equals(target)) {
results[i] = 1.0;
continue;
}
// 5. BFS 初始化
Queue<Map.Entry<String, Double>> queue = new LinkedList<>();
Map<String, Boolean> visited = new HashMap<>();
queue.add(new AbstractMap.SimpleEntry<>(start, 1.0)); // 初始元素
visited.put(start, true); // 标记为已访问
// 6. BFS 遍历图
while (!queue.isEmpty()) {
Map.Entry<String, Double> curr = queue.poll(); // 获取当前节点
String currVar = curr.getKey();
double currVal = curr.getValue();
// 7. 到达目标变量,记录结果并跳出循环
if (currVar.equals(target)) {
results[i] = currVal; // 更新结果
break; // 找到目标,结束当前查询
}
// 8. 遍历邻接节点
for (Map.Entry<String, Double> neighbor : graph.get(currVar).entrySet()) {
String nextVar = neighbor.getKey(); // 邻接变量
double nextVal = neighbor.getValue(); // 变量之间的值
// 如果邻接变量尚未访问,则继续 BFS
if (!visited.containsKey(nextVar)) {
visited.put(nextVar, true); // 标记已访问
queue.add(new AbstractMap.SimpleEntry<>(nextVar, currVal * nextVal)); // 更新路径值
}
}
}
}
// 9. 返回结果数组
return results;
}
}
class Solution {
// 存储有向图的邻接表
List<List<Integer>> edges;
// 记录每个节点的访问状态
int[] visited;
// 标记是否可以完成所有课程
boolean valid = true;
public boolean canFinish(int numCourses, int[][] prerequisites) {
// 初始化邻接表,每个课程对应一个列表,存储其后续课程
edges = new ArrayList<List<Integer>>();
for (int i = 0; i < numCourses; ++i) {
edges.add(new ArrayList<Integer>());
}
// 初始化访问状态数组,0 表示未访问,1 表示正在访问,2 表示已访问完成
visited = new int[numCourses];
// 根据先修课程关系构建邻接表
for (int[] info : prerequisites) {
edges.get(info[1]).add(info[0]);
}
// 遍历每个课程进行深度优先搜索
for (int i = 0; i < numCourses && valid; ++i) {
if (visited[i] == 0) {
// 如果课程未被访问,进行深度优先搜索
dfs(i);
}
}
// 返回是否可以完成所有课程的标志
return valid;
}
public void dfs(int u) {
// 将当前课程标记为正在访问
visited[u] = 1;
// 遍历当前课程的后续课程
for (int v : edges.get(u)) {
if (visited[v] == 0) {
// 如果后续课程未被访问,递归进行深度优先搜索
dfs(v);
if (!valid) {
// 如果在搜索过程中发现无法完成所有课程,直接返回
return;
}
} else if (visited[v] == 1) {
// 如果发现后续课程正在被访问,说明存在环,无法完成所有课程
valid = false;
return;
}
}
// 将当前课程标记为已访问完成
visited[u] = 2;
}
}
class Solution {
// 存储有向图
List<List<Integer>> edges;
// 标记每个节点的状态:0=未搜索,1=搜索中,2=已完成
int[] visited;
// 用数组来模拟栈,下标 n - 1 为栈底,0 为栈顶,存储拓扑排序结果
int[] result;
// 判断有向图中是否有环
boolean valid = true;
// 栈下标
int index;
public int[] findOrder(int numCourses, int[][] prerequisites) {
edges = new ArrayList<List<Integer>>();
// 初始化有向图,每个课程对应一个列表,存储其后续课程
for (int i = 0; i < numCourses; ++i) {
edges.add(new ArrayList<Integer>());
}
visited = new int[numCourses];
result = new int[numCourses];
index = numCourses - 1;
// 根据先修课程关系构建有向图
for (int[] info : prerequisites) {
edges.get(info[1]).add(info[0]);
}
// 每次挑选一个「未搜索」的节点,开始进行深度优先搜索
for (int i = 0; i < numCourses && valid; ++i) {
if (visited[i] == 0) {
dfs(i);
}
}
if (!valid) {
// 如果有环,返回空数组
return new int[0];
}
// 如果没有环,那么就有拓扑排序,返回结果数组
return result;
}
public void dfs(int u) {
// 将节点标记为「搜索中」
visited[u] = 1;
// 搜索其相邻节点
// 只要发现有环,立刻停止搜索
for (int v : edges.get(u)) {
// 如果「未搜索」那么搜索相邻节点
if (visited[v] == 0) {
dfs(v);
if (!valid) {
return;
}
}
// 如果「搜索中」说明找到了环
else if (visited[v] == 1) {
valid = false;
return;
}
}
// 将节点标记为「已完成」
visited[u] = 2;
// 将节点入栈,栈底在数组末尾,栈顶在数组开头
result[index--] = u;
}
}