Schedule dependent services with layered startup
Company: Snowflake
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
Quick Answer: This question evaluates understanding of graph algorithms (topological ordering and cycle detection), layered dependency extraction, and parallel scheduling under resource constraints, testing algorithm design and complexity reasoning in the Coding & Algorithms domain.
Service Startup Order (Topological Sort with Cycle Detection)
Constraints
- 0 <= n <= 10^5
- 0 <= edges.length <= 2 * 10^5
- Each edge is [u, v] with 0 <= u, v < n and u != v
- Return [] if and only if the dependency graph contains a cycle
Examples
Input: (4, [[0, 1], [0, 2], [1, 3], [2, 3]])
Expected Output: [0, 1, 2, 3]
Explanation: 0 has no dependencies, so it starts first; 1 and 2 depend only on 0; 3 depends on both 1 and 2 and comes last.
Input: (3, [[0, 1], [1, 2], [2, 0]])
Expected Output: []
Explanation: 0->1->2->0 forms a cycle, so no valid startup order exists.
Hints
- Compute the in-degree (number of unmet dependencies) of every service.
- Start with all services whose in-degree is 0 — these can start immediately.
- As each service 'starts', decrement its dependents' in-degrees; enqueue any that reach 0.
- If you process fewer than n services, the remaining ones are stuck in a cycle, so return [].
Dependency Layers (Level-by-Level Startup)
Constraints
- 0 <= n <= 10^5
- 0 <= edges.length <= 2 * 10^5
- Each edge is [u, v] with 0 <= u, v < n and u != v
- Within each layer, ids must be in ascending order
- Return [] if and only if the dependency graph contains a cycle
Examples
Input: (4, [[0, 1], [0, 2], [1, 3], [2, 3]])
Expected Output: [[0], [1, 2], [3]]
Explanation: Layer 0: {0}; layer 1: {1,2} (both depend only on 0); layer 2: {3} (depends on 1 and 2).
Input: (3, [[0, 1], [1, 2], [2, 0]])
Expected Output: []
Explanation: The cycle 0->1->2->0 leaves no service with in-degree 0, so no layering is possible.
Hints
- Run Kahn's algorithm, but process the queue one full level at a time (like BFS levels).
- Snapshot the current queue size before draining the layer — everything in it belongs to the same layer.
- Sort each layer's ids before adding it to the result for deterministic output.
- If the total number of placed services is less than n, a cycle exists, so return [].
Minimum Startup Makespan on K Cores
Constraints
- 0 <= n <= 10^5
- 0 <= edges.length <= 2 * 10^5
- 1 <= k <= n (when n >= 1)
- 0 <= t[i] <= 10^9
- Each edge is [u, v] with 0 <= u, v < n and u != v
- Return -1 if and only if the dependency graph contains a cycle
Examples
Input: (4, [[0, 1], [0, 2], [1, 3], [2, 3]], [1, 2, 3, 4], 2)
Expected Output: 8
Explanation: 0 runs [0,1]; then 1 ([1,3]) and 2 ([1,4]) run in parallel on 2 cores; 3 starts at 4 and finishes at 8.
Input: (3, [], [5, 2, 4], 1)
Expected Output: 11
Explanation: With 1 core and no dependencies, services run back to back: 5 + 2 + 4 = 11.
Hints
- A service is ready only after every dependency finishes — track unmet dependency counts like Kahn's algorithm.
- Use a min-heap of ready service ids (smallest-id tie-break) and a min-heap of running services keyed by finish time.
- Fill all free cores with ready services, then jump time forward to the next finish event and release those cores.
- When a service finishes, decrement its dependents' counts and enqueue any that become ready. If fewer than n services ever finish, there is a cycle: return -1.