LeetCode 1462. Course Schedule IV

There are a total of n courses you have to take, labeled from 0 to n-1.
Some courses may have direct prerequisites, for example, to take course 0 you have first to take course 1, which is expressed as a pair: [1,0]
Given the total number of courses n, a list of direct prerequisite pairs and a list of queries pairs.
You should answer for each queries[i] whether the course queries[i][0] is a prerequisite of the course queries[i][1] or not.
Return a list of boolean, the answers to the given queries.
Please note that if course a is a prerequisite of course b and course b is a prerequisite of course c, then, course a is a prerequisite of course c.

the description has already explain it pretty clearly.
so we have to construct the graph based on the given prerequisites.
so the graph we gonna construct will be a directed graph. and for each query, we should check query[0] is the prerequiesite pf query[1] or not.
the way to check that is to dfs this graph and if we meet query[0] and query[1] at a branch and in the right order(meet query[0] first and then query[1]), if any of the needs not met, then return false for this query.

but i came up with the solution that use bfs, and that requires us to check each queries one at a time.
so when we have a large amount of queries, it might be TLE, and the truth is: it is TLE when queries are too much.
the TLE code are as follows:

class Solution {
     
    public List<Boolean> checkIfPrerequisite(int n, int[][] prerequisites, int[][] queries) {
     
        //HashMap> map = new HashMap<>();
        
        List<Integer>[] map = new ArrayList[n];
        for (int i = 0; i < n; i++) {
     
            map[i] = new ArrayList<>();
        }
        for (int[] pre: prerequisites) {
     
            map[pre[0]].add(pre[1]); //pre and it's neighbors
        }
        
        //contrcuted the graph
        int m = queries.length;
        List<Boolean> res = new ArrayList<>();
        for (int[] query: queries) {
     
            int pre = query[0];
            int cur = query[1];
            res.add(bfs(map, pre, cur));
        }
        return res;
    }
    
    private boolean bfs(List<Integer>[] map, int pre, int cur) {
     
        
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(pre);
        
        while (!queue.isEmpty()) {
     
            int node = queue.poll();
            int size = map[node].size();
            for (int i = 0; i < size; i++) {
     
                if (map[node].get(i) == cur) {
     
                    return true;
                }
                queue.offer((map[node].get(i)));
            }                
        }
        return false;
    }
}

from what I saw in the discussion section, no one is using BFS.

the most common ways used in those solutions are: Flofy-warshall, DFS and topological sort.
before we divide in the floyd warshall problems, let’s think about what is the relations between this problem and this algorithm.
as we known, FW algorithm is used to find the shortest distance from any node pairs in a graph, but why does it have anything to do with this problem? the tricky thing is, we use the idea of this instead of it original code, because this idea is based on DP too.

so for each array in prerequisite, we seen them as a connection between them.
so now we need to check if there is any connection between i and j, so it will be either a directed connection between i and j, or it will pass some k(inner node)
so the code is very easy to implement:

class Solution {
     
    public List<Boolean> checkIfPrerequisite(int n, int[][] prerequisites, int[][] queries) {
     
        //HashMap> map = new HashMap<>();
        
        List<Boolean> res = new ArrayList<>();
        boolean[][] connected = new boolean[n][n];
        for (int[] pre: prerequisites) {
     
            int node1 = pre[0];
            int node2 = pre[1];
            connected[node2][node1] = true;//node2->node1, and node2 is the pre of node1
        }
        
        for(int k = 0; k < n; k++) {
     
            for (int i = 0; i < n; i++) {
     
                for (int j = 0; j < n; j++) {
     
                    connected[i][j] = connected[i][j] || (connected[i][k] && connected[k][j]);
                }
            }
        }
        for (int[] query: queries) {
     
            int node1 = query[0];
            int node2 = query[1]; //this is the pre
            if (connected[node2][node1]) {
      //if it is
                res.add(true);
            } else {
     
                res.add(false);
            }
        }
        return res;  
    }
}

你可能感兴趣的:(LeetCode,Graph,LeetCode,Java)