There are a total of n tasks you have to pick, labeled from 0 to n-1. Some tasks may have prerequisites tasks, for example to pick task 0 you have to first finish tasks 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: 2, [[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: 4, [[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].

**Asked In:** Google, Twitter, Amazon and many more companies.

**Solution: ** We can consider this problem as a graph (related to topological sorting) problem. 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 (because in that case there is no any topological order of tasks). Both BFS and DFS can be used for topological sorting to solve it.

Since pair is inconvenient for the implementation of graph algorithms, we first transform it to a graph. If task u is a prerequisite of task v, we will add a directed edge from node u to node v.

**Topological Sorting using BFS**

Here we use Kahn’s algorithm for topological sorting. BFS uses the indegrees of each node. We will first try to find a node with 0 indegree. If we fail to do so, there must be a cycle in the graph and we return false. Otherwise we have found one. We 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.

`// CPP program to find order to process tasks ` `// so that all tasks can be finished. This program ` `// mainly uses Kahn's algorithm. ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Returns adjacency list representation of graph from ` `// given set of pairs. ` `vector<unordered_set<` `int` `> > make_graph(` `int` `numTasks, ` ` ` `vector<pair<` `int` `, ` `int` `> >& prerequisites) ` `{ ` ` ` `vector<unordered_set<` `int` `> > graph(numTasks); ` ` ` `for` `(` `auto` `pre : prerequisites) ` ` ` `graph[pre.second].insert(pre.first); ` ` ` `return` `graph; ` `} ` ` ` `// Computes in-degree of every vertex ` `vector<` `int` `> compute_indegree(vector<unordered_set<` `int` `> >& 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<pair<` `int` `, ` `int` `> >& prerequisites) ` `{ ` ` ` `// Create an adjacency list ` ` ` `vector<unordered_set<` `int` `> > 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<pair<` `int` `, ` `int` `> > 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; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

0 1 2 3

**Topological Sorting using DFS:**

In this implementation, we use DFS based algorithm for Topological Sort.

`// CPP program to find Topological sorting using ` `// DFS ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Returns adjacency list representation of graph from ` `// given set of pairs. ` `vector<unordered_set<` `int` `> > make_graph(` `int` `numTasks, ` ` ` `vector<pair<` `int` `, ` `int` `> >& prerequisites) ` `{ ` ` ` `vector<unordered_set<` `int` `> > graph(numTasks); ` ` ` `for` `(` `auto` `pre : prerequisites) ` ` ` `graph[pre.second].insert(pre.first); ` ` ` `return` `graph; ` `} ` ` ` `// Does DFS and adds nodes to Topological Sort ` `bool` `dfs(vector<unordered_set<` `int` `> >& 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<pair<` `int` `, ` `int` `> >& prerequisites) ` `{ ` ` ` `vector<unordered_set<` `int` `> > 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<pair<` `int` `, ` `int` `> > 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; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

0 1 2 3

**Reference:** https://leetcode.com/problems/course-schedule-ii/

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Find whether it is possible to finish all tasks or not from given dependencies
- Print completed tasks at end according to Dependencies
- Find dependencies of each Vertex in a Directed Graph
- Sum of dependencies in a graph
- Find time taken to execute the tasks in A based on the order of execution in B
- Lexicographically Smallest Topological Ordering
- Find minimum value of y for the given x values in Q queries from all the given set of lines
- Union-Find Algorithm | (Union By Rank and Find by Optimized Path Compression)
- Find Itinerary from a given list of tickets
- Given a sorted dictionary of an alien language, find order of characters
- Find all reachable nodes from every node present in a given set
- Find the smallest binary digit multiple of given number
- Given two numbers a and b find all x such that a % x = b
- Find words which are greater than given length k
- Find Largest Special Prime which is less than or equal to a given number
- Find the maximum node at a given level in a binary tree
- Find the largest after deleting the given elements
- Find the Initial Array from given array after range sum queries
- Find any pair with given GCD and LCM
- Find the value of max(f(x)) - min(f(x)) for a given F(x)

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.