802. 找到最终的安全状态
参见官方题解
题目没读懂,看了题解才知道
是要找到在环中的节点,或者当前节点出发能达到环的节点
解法选择
- dfs + 三色标记
- 拓扑排序(没看)
dfs + 三色标记 思路
- 使用 color 数组标记每个节点的使用情况:
- 0,白色:节点尚未访问;
- 1,灰色:正在访问或者已经成环;
- 2,黑色:访问完事,且是安全的
- dfs
- 递归三部曲
- 函数参数和返回类型:
public boolean isSafe(int[][] graph, int[] color, int x)
- 终止条件:
- 当前节点是灰色,则表明不安全,return false;
- 当前节点是黑色,则表明安全,return true;
- 单层逻辑
- 若当前节点是白色,则单层逻辑首先将其标记为灰色;
- 然后,dfs遍历当前节点的邻居节点 graph[x];
- 能正常返回,表明是安全的,标记位 黑色
- 函数参数和返回类型:
- 递归三部曲
- 整体代码
- 一遍for遍历所有节点
- 如果当前节点是安全的,即 isSafe == true,则将当前节点添加到结果集 res 中
class Solution {
public List<Integer> eventualSafeNodes(int[][] graph) {
List<Integer> res = new ArrayList<>();
int[] color = new int[graph.length];
for (int i = 0; i < graph.length; i++) {
if (isSafe(graph, color, i)) { // 安全
res.add(i);
}
}
return res;
}
/**
* @param color 标记数组。0,节点尚未访问;1,正在访问或者已经成环;2,安全
* @param x 当前节点
*/
public boolean isSafe(int[][] graph, int[] color, int x) {
if (color[x] == 1) { // 成环
return false;
}
if (color[x] == 2) {
return true;
}
// 标记当前节点为 灰色
color[x] = 1;
for (int y : graph[x]) { // 遍历邻居节点
// isSafe(graph, color, y); // error
if (!isSafe(graph, color, y)) {
return false;
}
}
// 能正常返回,表明是安全的,标记位 黑色
color[x] = 2;
return true;
}
}