5947. 从给定原材料中找到所有可以做出的菜
作者:互联网
class Solution { // set判断原料是否存在 Set<String> supplySet = new HashSet<>(); // 已有的材料 Map<String, List<String>> map = new HashMap<>(); Map<String, Boolean> recipeInfo = new HashMap<>(); // 菜是否能做 Set<String> set = new HashSet<>(); // 判断是否判断过 public List<String> findAllRecipes(String[] recipes, List<List<String>> ingredients, String[] supplies) { for (int i = 0; i < supplies.length ; i++) { supplySet.add(supplies[i]); } int len = recipes.length; for (int i = 0; i <len; i++) { map.put(recipes[i], ingredients.get(i)); } Set<String> ans = new HashSet<>(); for (int i = 0; i < len; i++) { set.clear(); // 在该伦次中,判断菜是否判断过 if (dfs(recipes[i])) ans.add(recipes[i]); } return new ArrayList<>(ans); } // 只有菜才需要递归判断 public boolean dfs(String recipe) { // 递归判断 set.add(recipe); boolean flag = true; List<String> list = map.get(recipe); for (String item: list) { if (map.containsKey(item)) { // 是菜 if (set.contains(item)) { // 防止形成环 flag = false; break; } if (recipeInfo.containsKey(item)) { if (recipeInfo.get(item)) continue; flag = false; break; } if (!dfs(item)) { // 是使用的材料 flag = false; break; } } else if (!supplySet.contains(item)) { flag = false; break; } } recipeInfo.put(recipe, flag); return flag; } }
注意:在使用递归进行判断的时候,一定要用set判断一下这个菜是否判断过,因为防止循环引用,比如 a->b->c->a,经过几个轮次有需要重新从a开始。
!!!下次注意,防止超时
标签:5947,set,false,判断,item,flag,给定,new,原材料 来源: https://www.cnblogs.com/xiazhenbin/p/15733770.html