1
- // Runtime: 63 ms (Top 70.73%) | Memory: 73 MB (Top 78.21%)
2
- class Solution {
3
- private static final int NOT_VISITED = 0 ;
4
- private static final int VISITING = 1 ;
5
- private static final int VISITED = 2 ;
1
+ // Runtime: 32 ms (Top 86.45%) | Memory: 46.50 MB (Top 57.39%)
6
2
3
+ class Solution {
7
4
public List <String > findAllRecipes (String [] recipes , List <List <String >> ingredients , String [] supplies ) {
8
- Map <String , Integer > status = new HashMap <>();
9
- Map <String , List <String >> prereqs = new HashMap <>();
10
-
11
- for (int i = 0 ; i < recipes .length ; ++ i ) {
12
- status .put (recipes [i ], NOT_VISITED );
13
- prereqs .put (recipes [i ], ingredients .get (i ));
5
+ HashSet <String > sup = new HashSet <>();
6
+ HashMap <String , Integer > index = new HashMap <>();
7
+ HashMap <String , List <String >> map = new HashMap <>();
8
+
9
+ // create hashset of supplies
10
+ for (String s : supplies ) {
11
+ sup .add (s );
14
12
}
15
-
16
- for (String s : supplies ) {
17
- status .put (s , VISITED );
13
+
14
+ // store index of all recipes
15
+ for (int i = 0 ; i < recipes .length ; i ++) {
16
+ index .put (recipes [i ], i );
18
17
}
19
-
20
- List <String > output = new ArrayList <>();
21
- for (String s : recipes ) {
22
- dfs (s , prereqs , status , output );
23
- }
24
-
25
- return output ;
26
- }
27
-
28
- public boolean dfs (String s , Map <String , List <String >> prereqs , Map <String , Integer > status , List <String > output ) {
29
- if (!status .containsKey (s )) {
30
- return false ;
31
- }
32
-
33
- if (status .get (s ) == VISITING ) {
34
- return false ;
18
+
19
+ int [] indegree = new int [recipes .length ];
20
+ // create a mapping of all the recipes that are Ingredients as well
21
+ // to the recipes they are ingredients for
22
+ for (int i = 0 ; i < recipes .length ; i ++) {
23
+ for (String need : ingredients .get (i )) {
24
+ if (sup .contains (need ))
25
+ continue ;
26
+
27
+ map .putIfAbsent (need , new ArrayList <String >());
28
+ map .get (need ).add (recipes [i ]);
29
+ indegree [i ]++;
30
+ }
35
31
}
36
-
37
- if (status .get (s ) == VISITED ) {
38
- return true ;
32
+
33
+ LinkedList <Integer > q = new LinkedList <>();
34
+ // add all the recipes with indegree 0 to the queue
35
+ for (int i = 0 ; i < recipes .length ; i ++) {
36
+ if (indegree [i ] == 0 ) {
37
+ q .add (i );
38
+ }
39
39
}
40
-
41
- status .put (s , VISITING );
42
- for (String p : prereqs .get (s )) {
43
- if (!dfs (p , prereqs , status , output )) {
44
- return false ;
40
+
41
+ List <String > cooked = new ArrayList <>();
42
+ while (!q .isEmpty ()) {
43
+ int i = q .poll ();
44
+ cooked .add (recipes [i ]);
45
+
46
+ if (!map .containsKey (recipes [i ])) {
47
+ // if the map does not contain this recipe, this means
48
+ // this recipe is not an ingredient for any other recipe
49
+ // and no further processing is required
50
+ continue ;
51
+ }
52
+
53
+ for (String recipe : map .get (recipes [i ])) {
54
+ if (--indegree [index .get (recipe )] == 0 ) {
55
+ q .add (index .get (recipe ));
56
+ }
45
57
}
46
58
}
47
- status .put (s , VISITED );
48
- output .add (s );
49
-
50
- return true ;
59
+
60
+ return cooked ;
51
61
}
52
- }
62
+ }
0 commit comments