题目地址:
https://leetcode.com/problems/find-all-possible-recipes-from-given-supplies/
给定一个食物列表(以字符串数组形式给出),给出每个食物需要的原材料,以及已经有的原材料,每个原材料可以视为无限供应。有的食物也可以作为某另一个食物的原材料。求所有可以被做出来的食物。题目保证食物与原材料的依赖关系没有环。
可以将每个原材料和食物视为图的点,当食物需要某个原材料的时候,从该原材料向食物连边,然后从已有的原材料出发做拓扑排序,队列里出现过的元素即为可以做出来的食物。代码如下:
import java.util.*;
public class Solution {
public List<String> findAllRecipes(String[] recipes, List<List<String>> ingredients, String[] supplies) {
Map<String, Set<String>> g = new HashMap<>();
Map<String, Integer> ind = new HashMap<>();
for (int i = 0; i < recipes.length; i++) {
String re = recipes[i];
for (String s : ingredients.get(i)) {
g.putIfAbsent(s, new HashSet<>());
g.get(s).add(re);
ind.put(re, ind.getOrDefault(re, 0) + 1);
}
}
Queue<String> q = new LinkedList<>();
for (String s : supplies) {
q.offer(s);
}
Set<String> rec = new HashSet<>(Arrays.asList(recipes));
List<String> res = new ArrayList<>();
while (!q.isEmpty()) {
String s = q.poll();
if (rec.contains(s)) {
res.add(s);
}
if (g.containsKey(s)) {
for (String ne : g.get(s)) {
ind.put(ne, ind.get(ne) - 1);
if (ind.get(ne) == 0) {
q.offer(ne);
}
}
}
}
return res;
}
}
时空复杂度 O ( n l s ) O(nl_s) O(nls), n n n为图的点数, l s l_s ls为最长字符串长度。