LeetCode--207--medium--CourseSchedule

summary:

construct graph | dfs graph for finding if cycle exist

package myapp.kit.leetcode.graph;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Created with IDEA
 * author:Dingsheng Huang
 * Date:2020/4/15
 * Time:上午10:56
 *
 * 207
 * medium
 * https://leetcode.com/problems/course-schedule/
 *
 * There are a total of numCourses courses you have to take, labeled from 0 to numCourses-1.
 *
 * Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
 *
 * Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
 *
 *
 *
 * Example 1:
 *
 * Input: numCourses = 2, prerequisites = [[1,0]]
 * Output: true
 * Explanation: There are a total of 2 courses to take.
 *              To take course 1 you should have finished course 0. So it is possible.
 * Example 2:
 *
 * Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
 * Output: false
 * Explanation: There are a total of 2 courses to take.
 *              To take course 1 you should have finished course 0, and to take course 0 you should
 *              also have finished course 1. So it is impossible.
 *
 *
 * Constraints:
 *
 * The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
 * You may assume that there are no duplicate edges in the input prerequisites.
 * 1 <= numCourses <= 10^5
 *
 *
 */
public class CourseSchedule {

    // construct graph , dfs graph for find if circle exist
    // optimize
    public boolean canFinish2(int numCourses, int[][] prerequisites) {
        if (prerequisites.length == 0) {
            return true;
        }
        ArrayList<Integer>[] graph = new ArrayList[numCourses];
        for (int i = 0; i < numCourses; i++) {
            graph[i] = new ArrayList<>();
        }

        // pruning : using hash set filter unnecessary nodes
        int cn = 0;
        Set<Integer> set = new HashSet<>();
        Set<Integer> setFrom = new HashSet<>();
        for (int[] pair : prerequisites) {
            graph[pair[0]].add(pair[1]);
            if (!set.contains(pair[0])) {
                cn++;
                set.add(pair[0]);
                setFrom.add(pair[0]);
            }
            if (!set.contains(pair[1])) {
                cn++;
                set.add(pair[1]);
            }
        }

        for (int i : setFrom) {
            if (!dfs(i, 1, cn, graph)) {
                return false;
            }
        }
        return true;
    }

    public boolean dfs(int curr, int depth, int n, ArrayList<Integer>[] graph) {
        if (depth > n) {
            return false;
        }
        for (int i : graph[curr]) {
            if (!dfs(i, depth + 1, n, graph)) {
                return false;
            }
        }
        return true;
    }




    //  original intuition when I encounter this problem :

    private Map<Integer, Node> nodeMap = new HashMap<>();

    // construct graph , dfs
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        if (numCourses == 1 || prerequisites.length == 0) {
            return true;
        }
        constructGraph(prerequisites);
        for (Map.Entry<Integer, Node> entry : nodeMap.entrySet()) {
            if (!dfsGraph(new HashSet<>(), entry.getValue())) {
                return false;
            }
        }
        return true;
    }

    private void constructGraph(int[][] pairs) {
        for (int[] pair : pairs) {
            Node nodeFrom = null;
            if (nodeMap.containsKey(pair[0])) {
                nodeFrom = nodeMap.get(pair[0]);
            } else {
                nodeFrom = new Node(pair[0]);
                nodeMap.put(pair[0], nodeFrom);
            }

            Node nodeTo = null;
            if (nodeMap.containsKey(pair[1])) {
                nodeTo = nodeMap.get(pair[1]);
            } else {
                nodeTo = new Node(pair[1]);
                nodeMap.put(pair[1], nodeTo);
            }
            nodeFrom.neighbors.add(nodeTo);
        }
    }

    private boolean dfsGraph(Set<Node> visited, Node curr) {
        if (visited.contains(curr)) {
            return false;
        }
        visited.add(curr);
        for (Node next : curr.neighbors) {
            if (!dfsGraph(visited, next)) {
                return false;
            }
            // back track
            visited.remove(next);
        }
        return true;
    }

    private boolean dfsGraph2(int n, Node curr, int depth) {
        if (depth > n) {
            return false;
        }
        for (Node next : curr.neighbors) {
            if (!dfsGraph2(n, next, depth + 1)) {
                return false;
            }
        }
        return true;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值