Resolve Package Dependencies with Cycle Detection
AmazonSoftware Engineer · Technical ScreenLast updated
This problem tests your ability to perform a topological sort on a directed graph while identifying cyclic dependencies to ensure a safe build order.
Problem Statement
You are tasked with writing a build system component that resolves package dependencies. You are given a dictionary where keys are package names (strings) and values are lists of their direct dependencies (strings).
Implement a function resolve_build_order(package, dependency_map) that returns a list of all packages required to install the target package, ordered such that every dependency appears before the package that requires it. If a cycle is detected, or if a dependency is required but missing from the dependency_map, the function should raise an error or return an empty list/appropriate indicator.
Function Signature
def resolve_build_order(target, dependency_map):
# Returns a list of strings representing the installation order
pass
Constraints
dependency_mapcontains up to 10,000 packages.- Cycles must be detected and handled (do not enter an infinite loop).
- A package missing from the keys of
dependency_mapis considered a leaf node with no dependencies.
Example 1
Input:
dependency_map = {'A': ['B', 'C'], 'B': ['C'], 'C': []}, target = 'A'
Output: ['C', 'B', 'A']
Explanation: 'C' is a dependency of 'B' and 'A', so it must be installed first. 'B' depends on 'C', and 'A' depends on 'B' and 'C'.
Example 2
Input:
dependency_map = {'A': ['B'], 'B': ['A']}, target = 'A'
Output: Error (Cycle Detected)
Edge Cases
- Disconnected components that are not required by the target.
- Chains of dependencies of depth > 1000.
- Target package has no dependencies.
Hints
Hint 1
Consider representing the dependencies as a directed graph and performing a Depth First Search (DFS).
Hint 2
Use a tri-state approach (unvisited, visiting, visited) to keep track of nodes to detect cycles during your traversal.
Hint 3
The build order is equivalent to the reverse of the post-order traversal of the dependency graph.
Follow-up questions
- How would you modify your solution to support parallel installation of packages that do not share dependencies?
- What are the space and time complexity trade-offs if the dependency graph is extremely sparse versus extremely dense?
- How would you handle a scenario where packages might have multiple versions, and two different packages require different versions of the same library?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.