You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

给定食谱集合与已拥有食材集合,求解“添加哪种食材可解锁最多食谱”的高效算法选型

解决方案:动态计数+反向映射的高效查询架构

针对你提出的问题——在大规模食谱和食材集合中,快速找到添加后能解锁最多食谱的食材,同时支持动态添加/移除食材的需求,我设计了一套基于反向映射+状态维护的解决方案,完全满足你的性能要求。

核心思路拆解

首先明确问题本质:添加食材X后能完成的食谱,是那些当前仅缺失X的食谱(如果一个食谱缺失多种食材,添加X只是减少缺口数,但无法直接完成它)。我们的目标就是实时统计每个食材X对应的“仅缺X的食谱数量”,并能快速找到最大值对应的X。

关键数据结构设计

我们需要维护以下几个核心结构:

  • ingredient_to_recipes:反向映射字典,键是食材名称,值是包含该食材的所有食谱列表。用于快速找到某食材关联的所有食谱,是动态更新的基础。
  • missing_count:字典,键是食谱名称,值是该食谱当前缺失的食材数量。用于跟踪每个食谱的完成进度。
  • candidate_scores:字典,键是食材名称,值是添加该食材后能完成的食谱数量(即当前仅缺该食材的食谱数)。这是我们查询的核心数据。
  • score_to_ingredients(可选优化):字典,键是分数值,值是对应分数的食材列表。用于O(1)时间找到当前分数最高的食材,避免遍历所有食材。

预处理步骤

预处理可以一次性完成,复杂度可忽略:

  1. 构建ingredient_to_recipes:遍历所有食谱,将每个食材关联到对应的食谱列表,总时间复杂度O(M)(M是所有食谱的食材总数,因单食谱最多10种食材,M=10*N,N为食谱数)。
  2. 初始化missing_count:对每个食谱,统计其中未拥有的食材数量,时间复杂度O(M)。
  3. 初始化candidate_scores和score_to_ingredients:遍历每个食谱,如果missing_count[R] == 1,找到它唯一缺失的食材X,将candidate_scores[X] +=1,同时把X加入score_to_ingredients[1](如果该键不存在则创建)。时间复杂度O(M)。

动态更新流程

当添加食材X(将ingredients[X]从false改为true)

  1. 从ingredient_to_recipes中取出所有包含X的食谱列表。
  2. 遍历每个关联食谱R:
    • 如果X原本是R的缺失食材(即之前ingredients[X]为false):
      • 计算新的缺失数:new_missing = missing_count[R] - 1
      • 若原缺失数missing_count[R] == 1:
        • 这个食谱原本仅缺X,现在完成了,所以candidate_scores[X] -=1,同时更新score_to_ingredients(把X从原分数列表移除,若列表为空则删除该分数键)。
      • 若原缺失数missing_count[R] == 2:
        • 现在食谱仅缺另一种食材Y(遍历R的10种食材即可快速找到Y),所以candidate_scores[Y] +=1,更新score_to_ingredients(把Y加入新分数的列表)。
      • 更新missing_count[R]为new_missing。

当移除食材X(将ingredients[X]从true改为false)

  1. 从ingredient_to_recipes中取出所有包含X的食谱列表。
  2. 遍历每个关联食谱R:
    • 如果X原本是R的已拥有食材(即之前ingredients[X]为true):
      • 计算新的缺失数:new_missing = missing_count[R] + 1
      • 若原缺失数missing_count[R] == 0:
        • 这个食谱现在仅缺X,所以candidate_scores[X] +=1,更新score_to_ingredients(把X加入对应分数的列表)。
      • 若原缺失数missing_count[R] == 1:
        • 这个食谱原本仅缺Y,现在缺Y和X,所以candidate_scores[Y] -=1,更新score_to_ingredients(把Y从原分数列表移除)。
      • 更新missing_count[R]为new_missing。

查询操作

  • 若使用score_to_ingredients:直接取最大的分数键(可维护一个变量跟踪当前最大分数,避免每次取max()),对应的食材列表中的任意一个就是答案,时间复杂度O(1)。
  • 若未使用优化:遍历candidate_scores找到值最大的食材,时间复杂度O(K)(K为食材总数),适合食材数量不大的场景。

复杂度分析

  • 预处理:O(M),线性时间,完全可忽略。
  • 动态更新:每次操作处理的食谱数等于该食材关联的食谱数,每个食谱的处理是常数时间(因单食谱最多10种食材),所以每次更新的时间复杂度O(D)(D为关联食谱数)。
  • 查询:O(1)(优化后)或O(K)(未优化)。

问题归类说明

这个问题不属于NP问题,它是一个典型的动态计数问题,通过维护中间状态可以用多项式时间高效解决,不存在指数级复杂度的瓶颈。

内容的提问来源于stack exchange,提问作者Cody E

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 18:47:36