2115. Find All Possible Recipes from Given Supplies
T: O(V+E)
S: O(n*m + m), ingredients: n, recipes: m
class Solution {
public List<String> findAllRecipes(String[] recipes, List<List<String>> ingredients, String[] supplies) {
Map<String, List<String>> graph = new HashMap<>();
Map<String, Integer> indegree = new HashMap<>();
Set<String> recipesSet = new HashSet<>();
for (int i = 0; i < recipes.length; i++) {
recipesSet.add(recipes[i]);
for (int j = 0; j < ingredients.get(i).size(); j++) {
String from = ingredients.get(i).get(j);
String to = recipes[i];
graph.putIfAbsent(from, new ArrayList<>());
graph.get(from).add(to);
indegree.put(to, indegree.getOrDefault(to, 0)+1);
}
}
// this question's begin is using supplies
Queue<String> queue = new LinkedList<>();
for (String supply : supplies) {
queue.offer(supply);
}
List<String> res = new ArrayList<>();
while (!queue.isEmpty()) {
String from = queue.poll();
if (recipesSet.contains(from)) {
res.add(from);
}
for (String to : graph.getOrDefault(from, new ArrayList<>())) {
indegree.put(to, indegree.get(to) - 1);
if (indegree.get(to) == 0) {
queue.offer(to);
}
}
}
return res;
}
}
/*
recipes = ["bread","sandwich"], ingredients = [["yeast","flour"],["bread","meat"]]
supplies = ["yeast","flour","corn"]
"yeast", \bread
"flour" / \ sandwich
meat/
supplies = ["yeast","flour","meat"] => indegree = 0
"yeast" bread sandwich burger
"flour" meat meat
bread
use topology sort:
ingredients: from
recipes: to
supplies: are the begins
T: O(V+E)
S: O(n*m + m), ingredients: n, recipes: m
*/
better one:
class Solution {
public List<String> findAllRecipes(String[] recipes, List<List<String>> ingredients, String[] supplies) {
Set<String> recipeSet = new HashSet<>();
Map<String, Integer> indegree = new HashMap<>();
Map<String, List<String>> graph = buildGraph(recipes, ingredients, indegree, recipeSet);
Queue<String> queue = new LinkedList<>();
for (String supply : supplies) {
queue.offer(supply);
}
List<String> result = new ArrayList<>();
while (!queue.isEmpty()) {
String cur = queue.poll();
if (recipeSet.contains(cur)) {
result.add(cur);
}
for (String next : graph.getOrDefault(cur, new ArrayList<>())) {
indegree.put(next, indegree.getOrDefault(next, 0)-1);
if (indegree.get(next) == 0) {
queue.offer(next);
}
}
}
return result;
}
private Map<String, List<String>> buildGraph(String[] recipes, List<List<String>> ingredients, Map<String, Integer> indegree, Set<String> recipeSet) {
Map<String, List<String>> graph = new HashMap<>();
for (int i = 0; i < recipes.length; i++) {
String to = recipes[i];
recipeSet.add(to);
for (String from : ingredients.get(i)) {
graph.putIfAbsent(from, new ArrayList<>());
graph.get(from).add(to);
indegree.put(to, indegree.getOrDefault(to, 0) + 1);
}
}
return graph;
}
}
/*
["yeast","flour"] -> "bread"
["bread","meat"] -> sandwich
s
"yeast"
"flour" -> "bread" -> sandwich
"meat"
s
bread indree is 2
sandwich is 2
so when bread, sandwich indegree == 0 -> means we can arrive,
and we'll check when something arrive, is it existed in recipes
T: build graph: ingredients*recipes + supplies + topology sort O(V+E)
*/
Last updated