207.课程表

207. Course Schedule

207,课程表。题目链接

判断给定的图形是不是有环图,有两种解决办法是:深度优先搜索,和广度优先搜索

1.深度优先搜索

思路:使用一个onStack[]来判定当前访问到的节点是不是在当前的路径上,如果是,则证明有环

/**
 * 深度优先搜索判断环
 */
class Topological {
    private final int N;
    private List[] bags;
    private boolean[] marked;
    private boolean hasCycle = false;
    private boolean[] onStack;

    public Topological(int N, int[][] prerequisites) {
        this.N = N;
        bags = (List[]) new List[N];
        marked = new boolean[N];
        onStack = new boolean[N];
        for (int i = 0; i < N; i++) {
            bags[i] = new ArrayList<>();
        }
        for (int[] pre : prerequisites) {
            bags[pre[0]].add(pre[1]);
        }
        for (int v = 0; v < N; v++) {
            if (!marked[v])
                dfs(v);
        }
    }

    private void dfs(int v) {
        onStack[v] = true;
        marked[v] = true;
        for (int w : bags[v]) {
            if (hasCycle) return;
            if (!marked[w])
                dfs(w);
            else if (onStack[v] == onStack[w]) hasCycle = true;
        }
        onStack[v] = false;
    }

    public boolean isHasCycle() {
        return hasCycle;
    }
}

2.广度优先搜索:

有没有想起来教材数据结构,判定拓扑的方法.首先删掉入度为0的节点,然后删掉这个节点的链接.在判断其他节点是否入度为0.最后如果能够全部删除节点,证明无环

/**
 * 广度优先搜索判断环
 */
class Topological1 {
    private int N;
    private int[] inDegree; //入度表
    private List[] adj;

    public Topological1(int n, int[][] prerequisites) {
        N = n;
        inDegree = new int[N];
        adj = (List[]) new List[n];
        for (int i = 0; i < N; i++) {
            adj[i] = new ArrayList<>();
        }
        for (int[] pre : prerequisites) {
            inDegree[pre[1]]++;
            adj[pre[0]].add(pre[1]);
        }
        bfs();
    }

    private void bfs() {
        Queue queue = new ArrayDeque<>();
        for (int i = 0; i < N; i++) {
            if (inDegree[i] == 0) queue.add(i);
        }
        while (!queue.isEmpty()) {
            int v = queue.poll();
            N--;
            for (int w : adj[v]) {
              //删除节点的时候减去其他节点的入度
                if (--inDegree[w] == 0) queue.add(w);
            }
        }
    }

    public boolean hasCycle() {
        return N == 0;
    }
}

你可能感兴趣的:(207.课程表)