其他分享
首页 > 其他分享> > 5947. 从给定原材料中找到所有可以做出的菜

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