1+ /**
2+ * Question Link: https://leetcode.com/problems/find-all-possible-recipes-from-given-supplies/
3+ * Primary idea: Topological sort, keep each recipe with ingredients for a inDegree number and
4+ * to recipe list, use a queue to decrease inDegree and form the result
5+ *
6+ * Time Complexity: O(n ^ 2), Space Complexity: O(n + m),
7+ * n represents the length of recipes, m represents the length of supplies
8+ */
9+
10+ class FindAllPossibleRecipesGivenSupplies {
11+ func findAllRecipes( _ recipes: [ String ] , _ ingredients: [ [ String ] ] , _ supplies: [ String ] ) -> [ String ] {
12+ var ( inDegrees, toRecipes) = buildGraph ( recipes, ingredients)
13+ var res = [ String] ( ) , queue = supplies
14+
15+ while !queue. isEmpty {
16+ let food = queue. removeFirst ( )
17+
18+ for recipe in toRecipes [ food] ?? [ ] {
19+ inDegrees [ recipe] ! -= 1
20+
21+ if inDegrees [ recipe] == 0 {
22+ res. append ( recipe)
23+ queue. append ( recipe)
24+ }
25+ }
26+ }
27+
28+ return res
29+ }
30+
31+ private func buildGraph( _ recipes: [ String ] , _ ingredients: [ [ String ] ] ) -> ( [ String : Int ] , [ String : [ String ] ] ) {
32+ var inDegrees = [ String: Int] ( )
33+ var toRecipes = [ String: [ String] ] ( )
34+
35+ for i in 0 ..< recipes. count {
36+ let ( recipe, recipeIngredients) = ( recipes [ i] , ingredients [ i] )
37+
38+ for ingredient in recipeIngredients {
39+ inDegrees [ recipe, default: 0 ] += 1
40+ toRecipes [ ingredient, default: [ ] ] . append ( recipe)
41+ }
42+ }
43+
44+ return ( inDegrees, toRecipes)
45+ }
46+ }
0 commit comments