1136. Parallel Courses

LeetCode medium original: C# #array #csharp #graph #leetcode #math #medium
Le texte du problème est traduit du russe pour la langue sélectionnée. Le code reste inchangé.

Вам given entier n, которое указывает, что есть n курсов, обозначенных от 1 до n. Вам также дан tableau relations, где relations[i] = [prevCoursei, nextCoursei], представляющий собой зависимость между курсами: курс prevCoursei должен быть пройден до курса nextCoursei.

За один семестр вы можете взять любое количество курсов, при условии, что вы прошли все необходимые предварительные курсы в предыдущем семестре для тех курсов, которые вы собираетесь взять.

return минимальное количество семестров, необходимых для прохождения всех курсов. Если нет способа пройти все курсы, return -1.

Exemple:

Input: n = 3, relations = [[1,3],[2,3]]

Output: 2

Explanation: The figure above represents the given graph.

In the first semester, you can take courses 1 and 2.

In the second semester, you can take course 3.

C# solution

correspondant/original
public class Solution {
    public int MinimumSemesters(int N, int[][] relations) {
        var graph = new List<List<int>>(N + 1);
        for (int i = 0; i < N + 1; ++i) {
            graph.Add(new List<int>());
        }
        foreach (var relation in relations) {
            graph[relation[0]].Add(relation[1]);
        }
        var visited = new int[N + 1];
        for (int node = 1; node < N + 1; node++) {
            if (DfsCheckCycle(node, graph, visited) == -1) {
                return -1;
            }
        }
        var visitedLength = new int[N + 1];
        int maxLength = 1;
        for (int node = 1; node < N + 1; node++) {
            int length = DfsMaxPath(node, graph, visitedLength);
            maxLength = Math.Max(length, maxLength);
        }
        return maxLength;
    }
    private int DfsCheckCycle(int node, List<List<int>> graph, int[] visited) {
        if (visited[node] != 0) {
            return visited[node];
        } else {
            visited[node] = -1;
        }
        foreach (var endNode in graph[node]) {
            if (DfsCheckCycle(endNode, graph, visited) == -1) {
                return -1;
            }
        }
        visited[node] = 1;
        return 1;
    }
    private int DfsMaxPath(int node, List<List<int>> graph, int[] visitedLength) {
        if (visitedLength[node] != 0) {
            return visitedLength[node];
        }
        int maxLength = 1;
        foreach (var endNode in graph[node]) {
            int length = DfsMaxPath(endNode, graph, visitedLength);
            maxLength = Math.Max(length + 1, maxLength);
        }
        visitedLength[node] = maxLength;
        return maxLength;
    }
}

C++ solution

brouillon automatique, à relire avant soumission
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    public int MinimumSemesters(int N, int[][] relations) {
        var graph = new List<List<int>>(N + 1);
        for (int i = 0; i < N + 1; ++i) {
            graph.push_back(new List<int>());
        }
        foreach (var relation in relations) {
            graph[relation[0]].push_back(relation[1]);
        }
        var visited = new int[N + 1];
        for (int node = 1; node < N + 1; node++) {
            if (DfsCheckCycle(node, graph, visited) == -1) {
                return -1;
            }
        }
        var visitedLength = new int[N + 1];
        int maxLength = 1;
        for (int node = 1; node < N + 1; node++) {
            int length = DfsMaxPath(node, graph, visitedLength);
            maxLength = max(length, maxLength);
        }
        return maxLength;
    }
    private int DfsCheckCycle(int node, List<List<int>> graph, vector<int>& visited) {
        if (visited[node] != 0) {
            return visited[node];
        } else {
            visited[node] = -1;
        }
        foreach (var endNode in graph[node]) {
            if (DfsCheckCycle(endNode, graph, visited) == -1) {
                return -1;
            }
        }
        visited[node] = 1;
        return 1;
    }
    private int DfsMaxPath(int node, List<List<int>> graph, vector<int>& visitedLength) {
        if (visitedLength[node] != 0) {
            return visitedLength[node];
        }
        int maxLength = 1;
        foreach (var endNode in graph[node]) {
            int length = DfsMaxPath(endNode, graph, visitedLength);
            maxLength = max(length + 1, maxLength);
        }
        visitedLength[node] = maxLength;
        return maxLength;
    }
}

Java solution

correspondant/original
class Solution {
    public int minimumSemesters(int N, int[][] relations) {
        List<List<Integer>> graph = new ArrayList<>(N + 1);
        for (int i = 0; i < N + 1; ++i) {
            graph.add(new ArrayList<Integer>());
        }
        for (int[] relation : relations) {
            graph.get(relation[0]).add(relation[1]);
        }
        int[] visited = new int[N + 1];
        for (int node = 1; node < N + 1; node++) {
            if (dfsCheckCycle(node, graph, visited) == -1) {
                return -1;
            }
        }

        int[] visitedLength = new int[N + 1];
        int maxLength = 1;
        for (int node = 1; node < N + 1; node++) {
            int length = dfsMaxPath(node, graph, visitedLength);
            maxLength = Math.max(length, maxLength);
        }
        return maxLength;
    }

    private int dfsCheckCycle(int node, List<List<Integer>> graph, int[] visited) {
        if (visited[node] != 0) {
            return visited[node];
        } else {
            visited[node] = -1;
        }
        for (int endNode : graph.get(node)) {
            if (dfsCheckCycle(endNode, graph, visited) == -1) {
                return -1;
            }
        }
        visited[node] = 1;
        return 1;
    }

    private int dfsMaxPath(int node, List<List<Integer>> graph, int[] visitedLength) {
        if (visitedLength[node] != 0) {
            return visitedLength[node];
        }
        int maxLength = 1;
        for (int endNode : graph.get(node)) {
            int length = dfsMaxPath(endNode, graph, visitedLength);
            maxLength = Math.max(length + 1, maxLength);
        }
        visitedLength[node] = maxLength;
        return maxLength;
    }
}

Python solution

correspondant/original
class Solution:
    def minimumSemesters(self, N: int, relations: List[List[int]]) -> int:
        graph = [[] for _ in range(N + 1)]
        for prev, next in relations:
            graph[prev].append(next)
        
        visited = [0] * (N + 1)
        for node in range(1, N + 1):
            if self.dfsCheckCycle(node, graph, visited) == -1:
                return -1
        
        visited_length = [0] * (N + 1)
        max_length = 1
        for node in range(1, N + 1):
            length = self.dfsMaxPath(node, graph, visited_length)
            max_length = max(length, max_length)
        return max_length
    
    def dfsCheckCycle(self, node, graph, visited):
        if visited[node] != 0:
            return visited[node]
        else:
            visited[node] = -1
        for end_node in graph[node]:
            if self.dfsCheckCycle(end_node, graph, visited) == -1:
                return -1
        visited[node] = 1
        return 1

    def dfsMaxPath(self, node, graph, visited_length):
        if visited_length[node] != 0:
            return visited_length[node]
        max_length = 1
        for end_node in graph[node]:
            length = self.dfsMaxPath(end_node, graph, visited_length)
            max_length = max(length + 1, max_length)
        visited_length[node] = max_length
        return max_length

Algorithm

Постройте направленный graphe из зависимостей (relations).

Реализуйте функцию dfsCheckCycle для проверки наличия цикла в grapheе.

Реализуйте функцию dfsMaxPath для вычисления длины самого длинного пути в grapheе. Если цикл найден, return -1. Иначе return длину самого длинного пути.

😎

Vacancies for this task

offres actives with overlapping task tags are affichés.

Toutes les offres
Il n'y a pas encore d'offres actives.