Katkat

Deterministic Task Execution Order

GoogleSoftware Engineer · Onsite

Last updated

This question tests the ability to implement Kahn's algorithm for topological sorting while using a min-priority queue to satisfy specific tie-breaking requirements.

Problem Statement

You are given a list of tasks, where each task is identified by an integer label from 0 to n-1. You are also given a list of dependencies, where [u, v] means task u must be completed before task v can begin.

Your goal is to return a valid execution order for all tasks. If there are multiple valid orders, you must always choose the task with the smallest numerical label among all currently 'ready' tasks (tasks whose dependencies have all been met). If it is impossible to complete all tasks (due to a circular dependency), return an empty list.

Function Signature

def get_task_order(n, dependencies):
    # n: int (number of tasks)
    # dependencies: List[List[int]]
    # returns: List[int]

Examples

Example 1: Input: n = 3, dependencies = [[1, 0], [2, 0]] Output: [1, 2, 0] Explanation: Both 1 and 2 have no incoming edges and are ready. We pick the smaller label 1 first, then 2. Finally, 0 becomes ready.

Example 2: Input: n = 2, dependencies = [[0, 1], [1, 0]] Output: [] Explanation: A cycle exists (0 depends on 1 and 1 depends on 0), so no valid order is possible.

Constraints

  • 1 <= n <= 10^5
  • 0 <= len(dependencies) <= 2 * 10^5
  • Task labels are in the range [0, n-1]

Edge Cases

  • Disconnected graph components.
  • No dependencies provided.
  • Graphs containing cycles.

Hints

Hint 1

Represent the dependencies as an adjacency list and keep track of the in-degree of each task.

Hint 2

Use a min-priority queue to store all tasks with an in-degree of 0 to ensure the smallest label is always processed first.

Hint 3

If the number of tasks in your final result is less than n, it implies that there was at least one cycle in the graph.

Follow-up questions

  • What is the time and space complexity of your solution in terms of tasks and dependencies?
  • How would your implementation change if we wanted to process tasks in reverse lexicographical order?
  • If the graph is very sparse, could you optimize the space complexity?