4 回答
TA贡献1780条经验 获得超1个赞
我们可以使用图论对这种方法进行实际的复杂性估计。“连接组件”方法将具有复杂性,其中是所有成分和菜肴的集合,并且是包含所有关系的集合,其中每个都是一道菜并且是菜肴的成分 。(即假设您将此图存储在邻接列表中,而不是邻接矩阵中)O(|V| + |E|)VE(a, b)abbG = (V, E)
在任何需要找出每道菜的所有成分才能找到结果的算法中,您都必须调查每道菜及其所有成分。这将导致需要时间的调查(即遍历),这意味着没有这样的算法可以比您的方法更好。O(|V| + |E|)
TA贡献1827条经验 获得超8个赞
让我们首先把这个问题变成一个图形问题。每道菜和每种成分都将是一个.菜肴和配料之间的每个关系都将是.vertexedge
让我们分析一下解决方案的最大大小。假设总体上有菜肴和配料,则最大溶液输出是当每道菜都相关时。在这种情况下,输出的大小,因此这是您可以实现的时间复杂度的下限。我们可以很容易地创建一个输入,我们必须迭代所有顶点和边,因此时间复杂度的另一个下限是 。此外,我们必须保存所有顶点和边,因此空间复杂性的下限也是如此。NMN^2N * MM * N
现在,让我们分析一下您的解决方案。您迭代所有菜肴=,对于每个菜肴,您迭代所有值=,并与您一起检查字典中是否如此。你的空间复杂性也是如此。我会说你的解决方案很好。NMO(1)O(N * M)O(M * N)
TA贡献1869条经验 获得超4个赞
让我们首先把这个问题变成一个图形问题。每道菜和每种成分都将是一个.菜肴和配料之间的每个关系都将是.vertexedge
让我们分析一下解决方案的最大大小。假设总体上有菜肴和配料,则最大溶液输出是当每道菜都相关时。在这种情况下,输出的大小,因此这是您可以实现的时间复杂度的下限。我们可以很容易地创建一个输入,我们必须迭代所有顶点和边,因此时间复杂度的另一个下限是 。此外,我们必须保存所有顶点和边,因此空间复杂性的下限也是如此。NMN^2N * MM * N
现在,让我们分析一下您的解决方案。您迭代所有菜肴=,对于每个菜肴,您迭代所有值=,并与您一起检查字典中是否如此。你的空间复杂性也是如此。我会说你的解决方案很好。NMO(1)O(N * M)O(M * N)
TA贡献1820条经验 获得超9个赞
你只需要在这里建立一个反向地图。
我认为你可以通过使用Java8中引入的API以更富有表现力的方式编写代码。Stream
基本步骤:
从地图中提取所有成分
对于每种成分,获得一组菜肴,您将拥有许多这样的集合 - 将所有此类集合收集到一个集合中 - 因此该方法的返回类型变为
Set<Set<String>>
以下是实现:
private static Set<Set<String>> buildReverseMap(Map<String, Set<String>> map) {
// extracting all the values of map in a Set
Set<String> ingredients = map.values()
.stream()
.flatMap(Set::stream)
.collect(Collectors.toSet());
return ingredients.stream()
// map each ingredient to a set
.map(s ->
map.entrySet()
.stream()
.filter(entry -> entry.getValue().contains(s))
.map(Map.Entry::getKey)
.collect(Collectors.toSet())
).collect(Collectors.toSet());
}
时间复杂度分析:
假设你有菜肴和配料,在最坏的情况下,每个Dest可以有每种成分。对于每种成分,您需要迭代每道菜,并检查它是否包含当前成分。这种检查可以摊销完成,因为我们可以为每道菜提供配料。NMO(1)HashSet<String>
因此,对于每种成分,您将迭代每道菜,并检查该菜肴是否包含该成分。这给出了要摊销的时间复杂性。O(1)O(M*N)
空间复杂性分析:
就像在最坏的情况下一样,你可以让每个dist都由每种可用的成分组成。O(M*N)
注意:
您可以返回 ,而不仅仅是通过更改为List<Set<String>>Set<Set<String>>.collect(Collectors.toSet()).collect(Collectors.toList())
添加回答
举报
