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.
Input: (1, [])
Expected Output: [0]
Explanation: A single service with no dependencies starts on its own.
Input: (0, [])
Expected Output: []
Explanation: No services means an empty order.
Input: (5, [[1, 0], [2, 0], [3, 1], [3, 2], [4, 3]])
Expected Output: [4, 3, 1, 2, 0]
Explanation: Only service 4 has in-degree 0; it unlocks 3, which unlocks 1 and 2, which both unlock 0.
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.
Input: (1, [])
Expected Output: [[0]]
Explanation: A lone service forms a single layer.
Input: (0, [])
Expected Output: []
Explanation: No services produce no layers.
Input: (6, [[0, 2], [1, 2], [2, 3], [2, 4], [3, 5], [4, 5]])
Expected Output: [[0, 1], [2], [3, 4], [5]]
Explanation: 0 and 1 start together; 2 waits for both; 3 and 4 depend on 2; 5 waits for 3 and 4.
Input: (3, [])
Expected Output: [[0, 1, 2]]
Explanation: With no dependencies, all three services start in a single parallel layer.
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.
Input: (3, [], [5, 2, 4], 3)
Expected Output: 5
Explanation: With 3 cores all three start at time 0; the makespan is the longest service, 5.
Input: (3, [[0, 1], [1, 2], [2, 0]], [1, 1, 1], 2)
Expected Output: -1
Explanation: The cycle 0->1->2->0 means no service can ever start, so the schedule is impossible.
Input: (1, [], [7], 4)
Expected Output: 7
Explanation: A single service of length 7 finishes at time 7 regardless of core count.
Input: (0, [], [], 2)
Expected Output: 0
Explanation: No services means a makespan of 0.
Input: (5, [[0, 1], [0, 2], [1, 3], [2, 4]], [2, 3, 1, 5, 2], 1)
Expected Output: 13
Explanation: On 1 core, smallest-id ready scheduling runs 0,1,2,3,4 in that dependency-respecting order: 2+3+1+5+2 = 13.
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.