0
点赞
收藏
分享

微信扫一扫

找到最终的安全状态

酷子腿长一米八 2021-09-21 阅读 19
今日算法
题目描述:
示例 1:

示例 2:
题目分析
  • 求安全节点,最后必然在有限步内到达终点。也即是该节点不是环上的节点。
  • 可以利用求链表是否成环的思路。
思路一:
代码实现:
class Solution {
    public Set<Integer> set = new HashSet();
    public List<Integer> eventualSafeNodes(int[][] graph) {
        int row = graph.length;
        List<Integer> result = new ArrayList<Integer>();
        for (int i = 0; i < row; i++) {
            if (dfs(graph, i)) {
                result.add(i);
            }
        }
        return result;
    }
    public boolean dfs(int[][] graph, int index) {
        if (set.contains(index)) return false; // 该节点已经出现过,不安全节点
        set.add(index); // 加入当前正在遍历的节点
        for (int j : graph[index]) {
            if (dfs(graph, j)) {
                set.remove(j); // 移除安全节点
            } else {
                return false;
            }
        }
        return true;
    }
}
题解思路:
  • 0 未开始遍历的节点
  • 1 不安全节点或正在遍历中的节点
  • 2 安全节点
题解思路代码实现:
class Solution {
    public List<Integer> eventualSafeNodes(int[][] graph) {
        int row = graph.length;
        List<Integer> result = new ArrayList<Integer>();
        int[] arr = new int[row];
        for (int i = 0; i < row; i++) {
            if (dfs(graph, arr, i)) {
                result.add(i);
            }
        }
        return result;
    }
    public boolean dfs(int[][] graph, int[] arr, int index) {
        if (arr[index] > 0) return arr[index] == 2;
        arr[index] = 1;
        for (int j : graph[index]) {
            if (!dfs(graph, arr, j)) {
                return false;
            }
        }
        arr[index] = 2;
        return true;
    }
}
思路二:
代码实现:
class Solution {
    Map<Integer, ArrayList<Integer>> map = new HashMap();
    public List<Integer> eventualSafeNodes(int[][] graph) {
        List<Integer> result = new ArrayList();
        int row = graph.length; // 行数
        int[] len = new int[row]; // 记录每个节点的入度长度
        Queue<Integer> queue = new LinkedList();
        for (int i = 0; i < row; i++) {
            int col = graph[i].length;
            map.put(i, map.getOrDefault(i, new ArrayList<Integer>())); // 初始化容器.
            for (int j = 0; j < col; j++) {
                int colVal = graph[i][j];
                ArrayList<Integer> list = map.getOrDefault(colVal, new ArrayList<Integer>());
                list.add(i);
                map.put(colVal, list); // 翻转原图.
            }
            len[i] = col;// 节点i的入度为col
            if (col == 0) queue.offer(i); // 翻转节点中,原图终点即为现在的起点.
        }
        while (!queue.isEmpty()) {
            int num = queue.poll();
            for (int index : map.get(num)) {
                len[index]--; // 度减一
                if (len[index] == 0) queue.offer(index); // 入度为0的节点加入队列.
            }
        }
        for (int i = 0; i < row; i++) {
            if (len[i] == 0) result.add(i);
        }
        return result;
    }
}
举报

相关推荐

0 条评论