diff --git a/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/README.md b/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/README.md index dc1770289..12b1ecdc8 100755 --- a/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/README.md +++ b/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/README.md @@ -1,28 +1,43 @@ # [2115.Find All Possible Recipes from Given Supplies][title] -> [!WARNING|style:flat] -> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm) - ## Description +You have information about `n` different recipes. You are given a string array `recipes` and a 2D string array `ingredients`. The `ith` recipe has the name `recipes[i]`, and you can **create** it if you have **all** the needed ingredients from `ingredients[i]`. Ingredients to a recipe may need to be created from other recipes, i.e., `ingredients[i]` may contain a string that is in `recipes`. + +You are also given a string array `supplies` containing all the ingredients that you initially have, and you have an infinite supply of all of them. + +Return a list of all the recipes that you can create. You may return the answer in **any order**. + +Note that two recipes may contain each other in their ingredients. **Example 1:** ``` -Input: a = "11", b = "1" -Output: "100" +Input: recipes = ["bread"], ingredients = [["yeast","flour"]], supplies = ["yeast","flour","corn"] +Output: ["bread"] +Explanation: +We can create "bread" since we have the ingredients "yeast" and "flour". ``` -## 题意 -> ... - -## 题解 +**Example 2:** -### 思路1 -> ... -Find All Possible Recipes from Given Supplies -```go ``` +Input: recipes = ["bread","sandwich"], ingredients = [["yeast","flour"],["bread","meat"]], supplies = ["yeast","flour","meat"] +Output: ["bread","sandwich"] +Explanation: +We can create "bread" since we have the ingredients "yeast" and "flour". +We can create "sandwich" since we have the ingredient "meat" and can create the ingredient "bread". +``` + +**Example 3:** +``` +Input: recipes = ["bread","sandwich","burger"], ingredients = [["yeast","flour"],["bread","meat"],["sandwich","meat","bread"]], supplies = ["yeast","flour","meat"] +Output: ["bread","sandwich","burger"] +Explanation: +We can create "bread" since we have the ingredients "yeast" and "flour". +We can create "sandwich" since we have the ingredient "meat" and can create the ingredient "bread". +We can create "burger" since we have the ingredient "meat" and can create the ingredients "bread" and "sandwich". +``` ## 结语 diff --git a/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/Solution.go b/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/Solution.go index d115ccf5e..ddd92993f 100644 --- a/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/Solution.go +++ b/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/Solution.go @@ -1,5 +1,63 @@ package Solution -func Solution(x bool) bool { - return x +func Solution(recipes []string, ingredients [][]string, supplies []string) []string { + sm := make(map[string]struct{}) + rm := make(map[string]struct{}) + for _, s := range supplies { + sm[s] = struct{}{} + } + for _, r := range recipes { + rm[r] = struct{}{} + } + + in := make(map[string]int) + unlock := make(map[string][]string) + for idx, r := range recipes { + in[r] = 0 + for _, i := range ingredients[idx] { + if _, ok := sm[i]; ok { + continue + } + if i == r { + in[r] = -1 + break + } + if _, ok := rm[i]; ok { + in[r]++ + if _, ok := unlock[i]; !ok { + unlock[i] = []string{} + } + unlock[i] = append(unlock[i], r) + continue + } + in[r] = -1 // 无法组成,用了一些不存在的东西 + break + } + } + res := []string{} + queue := []string{} + for r, c := range in { + if c == 0 { + queue = append(queue, r) + res = append(res, r) + } + } + for len(queue) > 0 { + nq := make([]string, 0) + for _, cur := range queue { + for _, r := range unlock[cur] { + in[r]-- + if in[r] == 0 { + nq = append(nq, r) + res = append(res, r) + } + } + } + if len(nq) == 0 { + break + } + queue = nq + } + + return res } diff --git a/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/Solution_test.go b/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/Solution_test.go index 14ff50eb4..7bf7d2fd3 100644 --- a/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/Solution_test.go +++ b/leetcode/2101-2200/2115.Find-All-Possible-Recipes-from-Given-Supplies/Solution_test.go @@ -2,6 +2,7 @@ package Solution import ( "reflect" + "sort" "strconv" "testing" ) @@ -9,31 +10,34 @@ import ( func TestSolution(t *testing.T) { // 测试用例 cases := []struct { - name string - inputs bool - expect bool + name string + recipes []string + ingredients [][]string + supplies []string + expect []string }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", []string{"bread"}, [][]string{{"yeast", "flour"}}, []string{"yeast", "flour", "conr"}, []string{"bread"}}, + {"TestCase2", []string{"bread", "sandwich"}, [][]string{{"yeast", "flour"}, {"bread", "meat"}}, []string{"yeast", "flour", "meat"}, []string{"bread", "sandwich"}}, + {"TestCase3", []string{"bread", "sandwich", "burger"}, [][]string{{"yeast", "flour"}, {"bread", "meat"}, {"sandwich", "meat", "bread"}}, []string{"yeast", "flour", "meat"}, []string{"bread", "burger", "sandwich"}}, } // 开始测试 for i, c := range cases { t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { - got := Solution(c.inputs) + got := Solution(c.recipes, c.ingredients, c.supplies) + sort.Strings(got) if !reflect.DeepEqual(got, c.expect) { - t.Fatalf("expected: %v, but got: %v, with inputs: %v", - c.expect, got, c.inputs) + t.Fatalf("expected: %v, but got: %v, with inputs: %v %v %v", + c.expect, got, c.recipes, c.ingredients, c.supplies) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }