LeetCode每日一题:802 找到最终安全状态
Posted 遨游java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode每日一题:802 找到最终安全状态相关的知识,希望对你有一定的参考价值。
题目描述:
在有向图中,我们从某个节点出发和每个转向出开始,沿着有向图的边走。如果我们到达的节点是终点(即它没有连出的有向边),我们停止
现在,如果我们最后能走到终点,那么我们的起始节点是最终安全的。更具体的说,存在一个自然数k,无论选择从哪里开始行走,我们走了不
到k步必能停止在一个终点。
那些节点是安全的?返回一个有序的数组
解题原理:
这道题的实质:就是从一个节点出发,看沿路有没有环
一、先说一个解决图问题的模板套路
该套路不能在LeetCode中通过该题,时间主要浪费在了建图上。
但是,图的题一般不会出现在面试中,笔试中较为常见。该模板可以解决这一系列问题。平时练习熟悉,笔试套用即可。
1、建图的节点
import java.util.ArrayList;
import java.util.List;
public class Node {
int value;
// 出度
int in;
// 入度
int out;
// 下个节点
List<Node> next;
// 节点边的信息,比如:权重之类的
List<Integer> edgeInfo;
public Node(int value){
this.value = value;
next = new ArrayList<>();
edgeInfo = new ArrayList<>();
}
}
2、根据题目建图,一般题目给的是矩阵。以该题为例
private HashMap<Integer,Node> createGraph(int[][] graph){
HashMap<Integer,Node> nodes = new HashMap<>();
for(int i=0;i<graph.length;i++){
Node a = null;
if(nodes.containsKey(i)){
a = nodes.get(i);
}else{
a = new Node(i);
nodes.put(i,a);
}
for(int j=0;j<graph[i].length;j++){
Node b = null;
if(nodes.containsKey(graph[i][j])){
b = nodes.get(graph[i][j]);
}else{
b = new Node(graph[i][j]);
nodes.put(graph[i][j],b);
}
a.nexts.add(b);
}
}
return nodes;
}
3、根据深度优先遍历判断有环无环
// 0表示该节点还没有被访问过,1表示该节点正在访问中,2表示该节点被访问过。
private boolean dfs(Node a,int[] color){
if(a==null){
return true;
}
if(color[a.value]==1){
return false;
}
color[a.value] = 1;
for(Node next : a.nexts){
if(color[next.value]==1){
return false;
}
if(!dfs(next,color)){
return false;
}
color[next.value] = 2;
}
return true;
}
4、选出符合题意的节点
public List<Integer> eventualSafeNodes(int[][] graph) {
HashMap<Integer,Node> nodes = createGraph(graph);
List<Integer> result = new ArrayList<>();
for(int key : nodes.keySet()){
Node head = nodes.get(key);
if(dfs(head,new int[nodes.size()])) {
result.add(head.value);
}
}
return result;
}
二、LeetCode官方解
class Solution {
/**
说明:我拿的官方答案过得,官方答案跟我的区别是:
官方直接在矩阵上操作,而我用HashMap建图,时间主要浪费在了建图上
dfs那部分跟官方一样。时间复杂度都一样
*/
public List<Integer> eventualSafeNodes(int[][] graph) {
int N = graph.length;
int[] color = new int[N];
List<Integer> ans = new ArrayList();
for (int i = 0; i < N; ++i)
if (dfs(i, color, graph))
ans.add(i);
return ans;
}
// colors: WHITE 0, GRAY 1, BLACK 2;
public boolean dfs(int node, int[] color, int[][] graph) {
if (color[node] > 0)
return color[node] == 2;
color[node] = 1;
for (int nei: graph[node]) {
if (color[node] == 2)
continue;
if (color[nei] == 1 || !dfs(nei, color, graph))
return false;
}
color[node] = 2;
return true;
}
}
以上是关于LeetCode每日一题:802 找到最终安全状态的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode802. 找到最终的安全状态(图论三色标记法拓扑排序)/847. 访问所有节点的最短路径(特殊的bfs,状态压缩,dp)
[LeetCode] 802. Find Eventual Safe States 找到最终的安全状态
leetcode 802. 找到最终的安全状态(Find Eventual Safe States)