# Find the ordering of task from given dependencies (Course Schedule II)

Last Updated : 01 Dec, 2023

Given a total of N tasks that you have to pick, labelled from 0 to N-1. Some tasks may have prerequisite tasks, for example, to pick task 0 you have to first finish task 1, which is expressed as a pair: [0, 1] Given the total number of tasks and a list of prerequisite pairs, return the ordering of tasks you should pick to finish all tasks. There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all tasks, return an empty array.

Examples:

Input: N=2, Prerequisite_Pairs=[[1, 0]]
Output: [0, 1]
Explanation: There are a total of 2 tasks to pick. To pick task 1 you should have finished task 0. So the correct task order is [0, 1] .

Input: N=4, Prerequisite_Pairs=[[1, 0], [2, 0], [3, 1], [3, 2]]
Output: [0, 1, 2, 3] or [0, 2, 1, 3]
Explanation: There are a total of 4 tasks to pick. To pick task 3 you should have finished both tasks 1 and 2. Both tasks 1 and 2 should be pick after you finished task 0. So one correct task order is [0, 1, 2, 3]. Another correct ordering is [0, 2, 1, 3].

## Find the ordering of task from given dependencies using Topological Sorting using BFS:

Consider the Problem as a graph. All tasks are nodes of the graph and if task u is a prerequisite of task v, we will add a directed edge from node u to node v. Now, this problem is equivalent to finding a topological ordering of nodes/tasks (using topological sorting) in the graph represented by prerequisites. If there is a cycle in the graph, then it is not possible to finish all tasks. Here we use Kahn’s algorithm for topological sorting

Follow the steps to solve this problem:

• Store the indegrees of each node.
• First try to find a node with 0 indegree,
• If such node does not exist then there must be a cycle in the graph and we return false.
• Else set its indegree to be -1 to prevent from visiting it again and reduce the indegrees of all its neighbors by 1.
• This process will be repeated for N (number of nodes) times

Below is the implementation of above approach:

## CPP

 `// CPP program to find order to process tasks` `// so that all tasks can be finished. This program` `// mainly uses Kahn's algorithm.` `#include ` `using` `namespace` `std;`   `// Returns adjacency list representation of graph from` `// given set of pairs.` `vector > make_graph(``int` `numTasks,` `            ``vector >& prerequisites)` `{` `    ``vector > graph(numTasks);` `    ``for` `(``auto` `pre : prerequisites)` `        ``graph[pre.second].push_back(pre.first);` `    ``return` `graph;` `}`   `// Computes in-degree of every vertex` `vector<``int``> compute_indegree(vector >& graph)` `{` `    ``vector<``int``> degrees(graph.size(), 0);` `    ``for` `(``auto` `neighbors : graph)` `        ``for` `(``int` `neigh : neighbors)` `            ``degrees[neigh]++;` `    ``return` `degrees;` `}`   `// main function for topological sorting` `vector<``int``> findOrder(``int` `numTasks,` `        ``vector >& prerequisites)` `{` `    ``// Create an adjacency list` `    ``vector > graph =` `            ``make_graph(numTasks, prerequisites);`   `    ``// Find vertices of zero degree` `    ``vector<``int``> degrees = compute_indegree(graph);` `    ``queue<``int``> zeros;` `    ``for` `(``int` `i = 0; i < numTasks; i++)` `        ``if` `(!degrees[i])` `            ``zeros.push(i);`   `    ``// Find vertices in topological order` `    ``// starting with vertices of 0 degree` `    ``// and reducing degrees of adjacent.` `    ``vector<``int``> toposort;` `    ``for` `(``int` `i = 0; i < numTasks; i++) {` `        ``if` `(zeros.empty())` `            ``return` `{};` `        ``int` `zero = zeros.front();` `        ``zeros.pop();` `        ``toposort.push_back(zero);` `        ``for` `(``int` `neigh : graph[zero]) {` `            ``if` `(!--degrees[neigh])` `                ``zeros.push(neigh);` `        ``}` `    ``}` `    ``return` `toposort;` `}`   `// Driver code` `int` `main()` `{` `    ``int` `numTasks = 4;` `    ``vector > prerequisites;`   `    ``// for prerequisites: [[1, 0], [2, 1], [3, 2]]`   `    ``prerequisites.push_back(make_pair(1, 0));` `    ``prerequisites.push_back(make_pair(2, 1));` `    ``prerequisites.push_back(make_pair(3, 2));` `    ``vector<``int``> v = findOrder(numTasks, prerequisites);`   `    ``for` `(``int` `i = 0; i < v.size(); i++) {` `        ``cout << v[i] << ``" "``;` `    ``}`   `    ``return` `0;` `}`

## Java

 `// Java program to find order to process tasks` `// so that all tasks can be finished. This program` `// mainly uses Kahn's algorithm.`   `import` `java.util.ArrayList;` `import` `java.util.HashSet;` `import` `java.util.LinkedList;` `import` `java.util.Queue;`   `public` `class` `Dep {`   `    ``// Returns adjacency list representation of graph from` `    ``// given set of pairs.` `    ``static` `ArrayList >` `    ``make_graph(``int` `numTasks, ``int``[][] prerequisites)` `    ``{` `        ``ArrayList > graph` `            ``= ``new` `ArrayList>(numTasks);` `        ``for` `(``int` `i = ``0``; i < numTasks; i++)` `            ``graph.add(``new` `HashSet());` `        ``for` `(``int``[] pre : prerequisites)` `            ``graph.get(pre[``1``]).add(pre[``0``]);` `        ``return` `graph;` `    ``}`   `    ``// Computes in-degree of every vertex` `    ``static` `int``[] compute_indegree(` `        ``ArrayList > graph)` `    ``{` `        ``int``[] degrees = ``new` `int``[graph.size()];` `        ``for` `(HashSet neighbors : graph)` `            ``for` `(``int` `neigh : neighbors)` `                ``degrees[neigh]++;` `        ``return` `degrees;` `    ``}`   `    ``// main function for topological sorting` `    ``static` `ArrayList` `    ``findOrder(``int` `numTasks, ``int``[][] prerequisites)` `    ``{` `        ``// Create an adjacency list` `        ``ArrayList > graph` `            ``= make_graph(numTasks, prerequisites);`   `        ``// Find vertices of zero degree` `        ``int``[] degrees = compute_indegree(graph);` `        ``Queue zeros = ``new` `LinkedList();` `        ``for` `(``int` `i = ``0``; i < numTasks; i++)` `            ``if` `(degrees[i] == ``0``)` `                ``zeros.add(i);`   `        ``// Find vertices in topological order` `        ``// starting with vertices of 0 degree` `        ``// and reducing degrees of adjacent.` `        ``ArrayList toposort` `            ``= ``new` `ArrayList();` `        ``for` `(``int` `i = ``0``; i < numTasks; i++) {` `            ``if` `(zeros.isEmpty())` `                ``return` `new` `ArrayList();` `            ``int` `zero = zeros.peek();` `            ``zeros.poll();` `            ``toposort.add(zero);` `            ``for` `(``int` `neigh : graph.get(zero)) {` `                ``if` `(--degrees[neigh] == ``0``)` `                    ``zeros.add(neigh);` `            ``}` `        ``}` `        ``return` `toposort;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `numTasks = ``4``;` `        ``int``[][] prerequisites` `            ``= { { ``1``, ``0` `}, { ``2``, ``1` `}, { ``3``, ``2` `} };`   `        ``ArrayList v` `            ``= findOrder(numTasks, prerequisites);`   `        ``for` `(``int` `i = ``0``; i < v.size(); i++) {` `            ``System.out.print(v.get(i) + ``" "``);` `        ``}` `    ``}` `}`   `// This code is contributed by Lovely Jain`

## Python3

 `# Python program to find order to process tasks` `# so that all tasks can be finished. This program` `# mainly uses Kahn's algorithm.` `from` `collections ``import` `deque`   `# Returns adjacency list representation of graph from` `# given set of pairs.` `def` `make_graph(numTasks, prerequisites):` `    ``graph ``=` `[``set``() ``for` `_ ``in` `range``(numTasks)]` `    ``for` `u, v ``in` `prerequisites:` `        ``graph[v].add(u)` `    ``return` `graph`   `# Computes in-degree of every vertex` `def` `compute_indegree(graph):` `    ``indegrees ``=` `[``0``] ``*` `len``(graph)` `    ``for` `neighbors ``in` `graph:` `        ``for` `neigh ``in` `neighbors:` `            ``indegrees[neigh] ``+``=` `1` `    ``return` `indegrees`   `# main function for topological sorting` `def` `findOrder(numTasks, prerequisites):` `    ``# Create an adjacency list` `    ``graph ``=` `make_graph(numTasks, prerequisites)` `    `  `    ``# Find vertices of zero degree` `    ``indegrees ``=` `compute_indegree(graph)` `    ``zeros ``=` `deque([i ``for` `i, degree ``in` `enumerate``(indegrees) ``if` `degree ``=``=` `0``])` `    `  `    ``# Find vertices in topological order` `    ``# starting with vertices of 0 degree` `    ``# and reducing degrees of adjacent.` `    ``toposort ``=` `[]` `    ``while` `zeros:` `        ``zero ``=` `zeros.popleft()` `        ``toposort.append(zero)` `        ``for` `neigh ``in` `graph[zero]:` `            ``indegrees[neigh] ``-``=` `1` `            ``if` `indegrees[neigh] ``=``=` `0``:` `                ``zeros.append(neigh)` `    ``return` `toposort ``if` `len``(toposort) ``=``=` `numTasks ``else` `[]`   `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    ``numTasks ``=` `4` `    ``# for prerequisites: [[1, 0], [2, 1], [3, 2]]` `    ``prerequisites ``=` `[(``1``, ``0``), (``2``, ``1``), (``3``, ``2``)]` `    ``toposort ``=` `findOrder(numTasks, prerequisites)` `    ``print``(toposort)`   `# This code is contributed by Aman Kumar.`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `Dep` `{` `  `  `  ``// Returns adjacency list representation of graph from` `  ``// given set of pairs.` `  ``static` `List> MakeGraph(``int` `numTasks, ``int``[][] prerequisites)` `  ``{` `    ``List> graph = ``new` `List>(numTasks);` `    ``for` `(``int` `i = 0; i < numTasks; i++)` `      ``graph.Add(``new` `HashSet<``int``>());` `    ``foreach` `(``int``[] pre ``in` `prerequisites)` `      ``graph[pre[1]].Add(pre[0]);` `    ``return` `graph;` `  ``}`   `  ``// Computes in-degree of every vertex` `  ``static` `int``[] ComputeIndegree(List> graph)` `  ``{` `    ``int``[] degrees = ``new` `int``[graph.Count];` `    ``foreach` `(HashSet<``int``> neighbors ``in` `graph)` `      ``foreach` `(``int` `neigh ``in` `neighbors)` `        ``degrees[neigh]++;` `    ``return` `degrees;` `  ``}`   `  ``// Main function for topological sorting` `  ``static` `List<``int``> FindOrder(``int` `numTasks, ``int``[][] prerequisites)` `  ``{` `    ``// Create an adjacency list` `    ``List> graph = MakeGraph(numTasks, prerequisites);`   `    ``// Find vertices of zero degree` `    ``int``[] degrees = ComputeIndegree(graph);` `    ``Queue<``int``> zeros = ``new` `Queue<``int``>();` `    ``for` `(``int` `i = 0; i < numTasks; i++)` `      ``if` `(degrees[i] == 0)` `        ``zeros.Enqueue(i);`   `    ``// Find vertices in topological order` `    ``// starting with vertices of 0 degree` `    ``// and reducing degrees of adjacent.` `    ``List<``int``> toposort = ``new` `List<``int``>();` `    ``for` `(``int` `i = 0; i < numTasks; i++)` `    ``{` `      ``if` `(zeros.Count == 0)` `        ``return` `new` `List<``int``>();` `      ``int` `zero = zeros.Peek();` `      ``zeros.Dequeue();` `      ``toposort.Add(zero);` `      ``foreach` `(``int` `neigh ``in` `graph[zero])` `      ``{` `        ``if` `(--degrees[neigh] == 0)` `          ``zeros.Enqueue(neigh);` `      ``}` `    ``}` `    ``return` `toposort;` `  ``}`   `  ``// Driver code` `  ``static` `void` `Main(``string``[] args)` `  ``{` `    ``int` `numTasks = 4;` `    ``int``[][] prerequisites = ``new` `int``[][] { ``new` `int``[] { 1, 0 }, ``new` `int``[] { 2, 1 }, ``new` `int``[] { 3, 2 } };`   `    ``List<``int``> v = FindOrder(numTasks, prerequisites);`   `    ``Console.WriteLine(``string``.Join(``" "``, v));` `  ``}` `}`

## Javascript

 `// JavaScript program to find order to process tasks` `// so that all tasks can be finished. This program` `// mainly uses Kahn's algorithm.`   `// Returns adjacency list representation of graph from` `// given set of pairs.` `function` `make_graph(numTasks, prerequisites) {` `let graph = ``new` `Array(numTasks).fill(``null``).map(() => ``new` `Set());` `for` `(let i = 0; i < prerequisites.length; i++) {` `let pre = prerequisites[i];` `graph[pre[1]].add(pre[0]);` `}` `return` `graph;` `}`   `// Computes in-degree of every vertex` `function` `compute_indegree(graph) {` `let degrees = ``new` `Array(graph.length).fill(0);` `for` `(let neighbors of graph) {` `for` `(let neigh of neighbors) {` `degrees[neigh]++;` `}` `}` `return` `degrees;` `}`   `// main function for topological sorting` `function` `findOrder(numTasks, prerequisites) {` `// Create an adjacency list` `let graph = make_graph(numTasks, prerequisites);`   `// Find vertices of zero degree` `let degrees = compute_indegree(graph);` `let zeros = [];` `for` `(let i = 0; i < numTasks; i++) {` `if` `(degrees[i] === 0) {` `zeros.push(i);` `}` `}`   `// Find vertices in topological order` `// starting with vertices of 0 degree` `// and reducing degrees of adjacent.` `let toposort = [];` `for` `(let i = 0; i < numTasks; i++) {` `if` `(zeros.length === 0) {` `return` `[];` `}` `let zero = zeros.shift();` `toposort.push(zero);` `for` `(let neigh of graph[zero]) {` `if` `(--degrees[neigh] === 0) {` `zeros.push(neigh);` `}` `}` `}` `return` `toposort;` `}`   `// Driver code` `let numTasks = 4;` `let prerequisites = [[1, 0], [2, 1], [3, 2]];` `let v = findOrder(numTasks, prerequisites);`   `for` `(let i = 0; i < v.length; i++) {` `console.log(v[i] + ``" "``);` `}`   `// This code is contributed by Pushpesh Raj.`

Output

```0 1 2 3
```

Time complexity : O(N+E) where N is the number of tasks, and E is the number of prerequisite pairs.
Auxiliary Space:O(N+E)

## Find the ordering of task from given dependencies using Topological Sorting using DFS:

The idea is to use a topological sort algorithm with depth-first search (DFS) to find a valid ordering of tasks given prerequisite pairs. Construct a directed graph where tasks are nodes and prerequisites are directed edges. Perform DFS to identify a valid order, ensuring there are no cycles in the graph. If a valid order exists, it’s returned; otherwise, an empty array is returned, indicating that it’s not possible to find a valid order.

Follow the steps to solve this problem:

• Create a directed graph where tasks are nodes, and prerequisites are directed edges.
• Perform a depth-first search (DFS) to traverse the graph, maintaining a topological order and checking for cycles. If a cycle is found, return an empty array, indicating an impossible task order.
• If the DFS traversal completes without cycles, reverse the order obtained to obtain a valid topological ordering of tasks that satisfies all prerequisites.
• Return the valid task order or an empty array if it’s impossible to complete all tasks.

Below is the implementation of above approach:

## CPP

 `// CPP program to find Topological sorting using ` `// DFS ` `#include ` `using` `namespace` `std; ` `  `  `// Returns adjacency list representation of graph from ` `// given set of pairs. ` `vector > make_graph(``int` `numTasks, ` `             ``vector >& prerequisites) ` `{ ` `    ``vector > graph(numTasks); ` `    ``for` `(``auto` `pre : prerequisites) ` `        ``graph[pre.second].push_back(pre.first); ` `    ``return` `graph; ` `} ` `  `  `// Does DFS and adds nodes to Topological Sort ` `bool` `dfs(vector >& graph, ``int` `node,  ` `           ``vector<``bool``>& onpath, vector<``bool``>& visited,  ` `                                ``vector<``int``>& toposort) ` `{ ` `    ``if` `(visited[node]) ` `        ``return` `false``; ` `    ``onpath[node] = visited[node] = ``true``; ` `    ``for` `(``int` `neigh : graph[node]) ` `        ``if` `(onpath[neigh] || dfs(graph, neigh, onpath, visited, toposort)) ` `            ``return` `true``; ` `    ``toposort.push_back(node); ` `    ``return` `onpath[node] = ``false``; ` `} ` `  `  `// Returns an order of tasks so that all tasks can be ` `// finished. ` `vector<``int``> findOrder(``int` `numTasks, vector >& prerequisites) ` `{ ` `    ``vector > graph = make_graph(numTasks, prerequisites); ` `    ``vector<``int``> toposort; ` `    ``vector<``bool``> onpath(numTasks, ``false``), visited(numTasks, ``false``); ` `    ``for` `(``int` `i = 0; i < numTasks; i++) ` `        ``if` `(!visited[i] && dfs(graph, i, onpath, visited, toposort)) ` `            ``return` `{}; ` `    ``reverse(toposort.begin(), toposort.end()); ` `    ``return` `toposort; ` `} ` `  `  `int` `main() ` `{ ` `    ``int` `numTasks = 4; ` `    ``vector > prerequisites; ` `  `  `    ``// for prerequisites: [[1, 0], [2, 1], [3, 2]] ` `    ``prerequisites.push_back(make_pair(1, 0)); ` `    ``prerequisites.push_back(make_pair(2, 1)); ` `    ``prerequisites.push_back(make_pair(3, 2)); ` `    ``vector<``int``> v = findOrder(numTasks, prerequisites); ` `  `  `    ``for` `(``int` `i = 0; i < v.size(); i++) { ` `        ``cout << v[i] << ``" "``; ` `    ``} ` `  `  `    ``return` `0; ` `}`

## Java

 `// Java program to find Topological sorting using` `// DFS`   `import` `java.util.ArrayList;` `import` `java.util.Collections;` `import` `java.util.HashSet;`   `public` `class` `Dfs1 {`   `    ``// Returns adjacency list representation of graph from` `    ``// given set of pairs.` `    ``static` `ArrayList >` `    ``make_graph(``int` `numTasks, ``int``[][] prerequisites)` `    ``{` `        ``ArrayList > graph` `            ``= ``new` `ArrayList(numTasks);` `        ``for` `(``int` `i = ``0``; i < numTasks; i++)` `            ``graph.add(``new` `HashSet());` `        ``for` `(``int``[] pre : prerequisites)` `            ``graph.get(pre[``1``]).add(pre[``0``]);` `        ``return` `graph;` `    ``}`   `    ``// Does DFS and adds nodes to Topological Sort` `    ``static` `boolean` `dfs(ArrayList > graph,` `                       ``int` `node, ``boolean``[] onpath,` `                       ``boolean``[] visited,` `                       ``ArrayList toposort)` `    ``{` `        ``if` `(visited[node])` `            ``return` `false``;` `        ``onpath[node] = visited[node] = ``true``;` `        ``for` `(``int` `neigh : graph.get(node))` `            ``if` `(onpath[neigh]` `                ``|| dfs(graph, neigh, onpath, visited,` `                       ``toposort))` `                ``return` `true``;` `        ``toposort.add(node);` `        ``return` `onpath[node] = ``false``;` `    ``}`   `    ``// Returns an order of tasks so that all tasks can be` `    ``// finished.` `    ``static` `ArrayList` `    ``findOrder(``int` `numTasks, ``int``[][] prerequisites)` `    ``{` `        ``ArrayList > graph` `            ``= make_graph(numTasks, prerequisites);` `        ``ArrayList toposort` `            ``= ``new` `ArrayList();` `        ``boolean``[] onpath = ``new` `boolean``[numTasks];` `        ``boolean``[] visited = ``new` `boolean``[numTasks];` `        ``for` `(``int` `i = ``0``; i < numTasks; i++)` `            ``if` `(!visited[i]` `                ``&& dfs(graph, i, onpath, visited, toposort))` `                ``return` `new` `ArrayList();` `        ``Collections.reverse(toposort);` `        ``return` `toposort;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `numTasks = ``4``;` `        ``int``[][] prerequisites` `            ``= { { ``1``, ``0` `}, { ``2``, ``1` `}, { ``3``, ``2` `} };`   `        ``ArrayList v` `            ``= findOrder(numTasks, prerequisites);`   `        ``for` `(``int` `i = ``0``; i < v.size(); i++) {` `            ``System.out.print(v.get(i) + ``" "``);` `        ``}` `    ``}` `}`   `// This code is contributed by Lovely Jain`

## Python3

 `#  Python program to find Topological sorting using` `#  DFS`   `#  Returns adjacency list representation of graph from` `#  given set of pairs.` `def` `make_graph(numTasks, prerequisites):` `    ``graph ``=` `{i: [] ``for` `i ``in` `range``(numTasks)}` `    ``for` `pre ``in` `prerequisites:` `        ``graph[pre[``1``]].append(pre[``0``])` `    ``return` `graph`     `#  Does DFS and adds nodes to Topological Sort` `def` `dfs(graph, node, onpath, visited, toposort):` `    ``if` `visited[node]:` `        ``return` `False` `    ``onpath[node] ``=` `visited[node] ``=` `True` `    ``for` `neigh ``in` `graph[node]:` `        ``if` `onpath[neigh] ``or` `dfs(graph, neigh, onpath, visited, toposort):` `            ``return` `True` `    ``toposort.append(node)` `    ``return` `onpath[node] ``=``=` `False`     `#  Returns an order of tasks so that all tasks can be` `#  finished.` `def` `findOrder(numTasks, prerequisites):` `    ``graph ``=` `make_graph(numTasks, prerequisites)` `    ``toposort ``=` `[]` `    ``onpath ``=` `[``False` `for` `i ``in` `range``(numTasks)]` `    ``visited ``=` `[``False` `for` `i ``in` `range``(numTasks)]` `    ``for` `i ``in` `range``(numTasks):` `        ``if` `not` `visited[i] ``and` `dfs(graph, i, onpath, visited, toposort):` `            ``return` `    ``toposort ``=` `toposort[::``-``1``]` `    ``return` `toposort`   `# Driver code` `if` `__name__ ``=``=` `"__main__"``:` `    ``numTasks ``=` `4` `    ``prerequisites ``=` `[[``1``, ``0``], [``2``, ``1``], [``3``, ``2``]]` `    ``v ``=` `findOrder(numTasks, prerequisites)` `    ``for` `i ``in` `range``(``len``(v)):` `        ``print``(v[i], end``=``" "``)`

## C#

 `// C# program to find Topological sorting using ` `// DFS ` `using` `System;` `using` `System.Collections.Generic;` `using` `System.Linq;`   `class` `Solution {` `      ``// Returns adjacency list representation of graph from ` `    ``// given set of pairs. ` `    ``static` `List> MakeGraph(``int` `numTasks, List> prerequisites) {` `        ``var` `graph = ``new` `List>(numTasks);`   `        ``for` `(``int` `i = 0; i < numTasks; i++) {` `            ``graph.Add(``new` `HashSet<``int``>());` `        ``}`   `        ``foreach` `(``var` `pre ``in` `prerequisites) {` `            ``graph[pre.Item2].Add(pre.Item1);` `        ``}`   `        ``return` `graph;` `    ``}` `    ``// Does DFS and adds nodes to Topological Sort ` `    ``static` `bool` `DFS(List> graph, ``int` `node, HashSet<``int``> onPath, HashSet<``int``> visited, List<``int``> topoSort) {` `        ``if` `(visited.Contains(node)) {` `            ``return` `false``;` `        ``}`   `        ``onPath.Add(node);` `        ``visited.Add(node);`   `        ``foreach` `(``var` `neigh ``in` `graph[node]) {` `            ``if` `(onPath.Contains(neigh) || DFS(graph, neigh, onPath, visited, topoSort)) {` `                ``return` `true``;` `            ``}` `        ``}`   `        ``topoSort.Add(node);` `        ``onPath.Remove(node);`   `        ``return` `false``;` `    ``}` `    ``// Returns an order of tasks so that all tasks can be ` `    ``// finished. ` `    ``static` `List<``int``> FindOrder(``int` `numTasks, List> prerequisites) {` `        ``var` `graph = MakeGraph(numTasks, prerequisites);` `        ``var` `topoSort = ``new` `List<``int``>();` `        ``var` `onPath = ``new` `HashSet<``int``>();` `        ``var` `visited = ``new` `HashSet<``int``>();`   `        ``for` `(``int` `i = 0; i < numTasks; i++) {` `            ``if` `(!visited.Contains(i) && DFS(graph, i, onPath, visited, topoSort)) {` `                ``return` `new` `List<``int``>();` `            ``}` `        ``}`   `        ``topoSort.Reverse();` `        ``return` `topoSort;` `    ``}`   `    ``static` `void` `Main(``string``[] args) {` `        ``int` `numTasks = 4;` `          ``// for prerequisites: [[1, 0], [2, 1], [3, 2]] ` `        ``var` `prerequisites = ``new` `List> {` `            ``Tuple.Create(1, 0),` `            ``Tuple.Create(2, 1),` `            ``Tuple.Create(3, 2)` `        ``};`   `        ``var` `v = FindOrder(numTasks, prerequisites);`   `        ``foreach` `(``var` `i ``in` `v) {` `            ``Console.Write(i + ``" "``);` `        ``}` `    ``}` `}`   `// This code is contributed by Prince Kumar`

## Javascript

 `// Returns adjacency list representation of graph from` `// given set of pairs.` `function` `makeGraph(numTasks, prerequisites) {` `const graph = {};` `for` `(let i = 0; i < numTasks; i++) {` `graph[i] = [];` `}` `for` `(let i = 0; i < prerequisites.length; i++) {` `const pre = prerequisites[i];` `graph[pre[1]].push(pre[0]);` `}` `return` `graph;` `}`   `// Does DFS and adds nodes to Topological Sort` `function` `dfs(graph, node, onpath, visited, toposort) {` `if` `(visited[node]) {` `return` `false``;` `}` `onpath[node] = visited[node] = ``true``;` `for` `(let i = 0; i < graph[node].length; i++) {` `const neigh = graph[node][i];` `if` `(onpath[neigh] || dfs(graph, neigh, onpath, visited, toposort)) {` `return` `true``;` `}` `}` `toposort.push(node);` `return` `onpath[node] === ``false``;` `}`   `// Returns an order of tasks so that all tasks can be` `// finished.` `function` `findOrder(numTasks, prerequisites) {` `const graph = makeGraph(numTasks, prerequisites);` `const toposort = [];` `const onpath = ``new` `Array(numTasks).fill(``false``);` `const visited = ``new` `Array(numTasks).fill(``false``);` `for` `(let i = 0; i < numTasks; i++) {` `if` `(!visited[i] && dfs(graph, i, onpath, visited, toposort)) {` `return``;` `}` `}` `return` `toposort.reverse();` `}`   `// Driver code` `const numTasks = 4;` `const prerequisites = [[1, 0], [2, 1], [3, 2]];` `const v = findOrder(numTasks, prerequisites); temp=``""``;` `for` `(let i = 0; i < v.length; i++) {` `temp = temp +v[i] + ``" "``;` `} console.log(temp);`

Output

```0 1 2 3
```

Time complexity : O(N+E) where N is the number of tasks, and E is the number of prerequisite pairs.
Auxiliary Space:O(N+E)