You’re on a fintech risk team supporting an internal low-code/no-code platform used by 8,000 ops analysts to ship fraud-review workflows. A workflow is built from reusable “blocks” (KYC check, device fingerprint, sanctions screening). Before deployment, the platform must ensure blocks can be executed in a valid order and flag configuration mistakes that would cause runtime failures.
Each workflow is described by directed dependencies: if block A must run before block B, you’ll receive a pair [A, B]. Some workflows are huge (tens of thousands of blocks) and are deployed multiple times per day, so you need an efficient validator.
Given:
blocks: a list of unique block IDs (strings)dependencies: a list of pairs [before, after] meaning before -> afterReturn a list representing a valid execution order of all blocks such that every dependency is satisfied.
If no valid order exists (because of a cycle), return an empty list [].
blocks (assume inputs are consistent).Input:
blocks = ["kyc", "device", "sanctions", "score"]dependencies = [["kyc", "score"], ["device", "score"], ["sanctions", "score"]]Output:
["device", "kyc", "sanctions", "score"]Explanation: score must come after kyc, device, and sanctions. Among all valid orders, starting with device is lexicographically smallest.
Input:
blocks = ["a", "b", "c"]dependencies = [["a", "b"], ["b", "c"], ["c", "a"]]Output:
[]Explanation: The dependencies form a cycle, so no deployment order exists.
1 <= len(blocks) <= 2 * 10^40 <= len(dependencies) <= 2 * 10^51..20