使用嵌套哈希表解决此实践问题是否有效?

时间:2018-12-14 06:44:36

标签: algorithm performance data-structures hashmap hashtable

我的任务是找到以下问题的最有效解决方案:我需要在给定的年份(y)中打印出(k)最多流式电影(g),(y),我可以假设需要o(1)来检索当前年份。例如: 每次播放电影时,都会给我电影的名称和类型。  “在 2014 年内, 5 最受欢迎的 romance 电影是什么?

返回的答案可能类似于

  • MovieName1(浪漫)3409个流
  • MovieName2(浪漫)4000个流
  • MovieName3(浪漫)5340个流
  • MovieName4(浪漫)9000个流
  • MovieName5(浪漫)10000个流

所以我的思考过程是使用3个嵌套的哈希表。

  • 我在其中使用它们的名称(键)映射到频率(值)
  • 我使用流派(key)映射到地图(名称,频率)(值)的地方
  • 最后一个是我使用year(key)映射到地图(类型, 地图(名称,频率)(值)

这有什么意义吗...我想只是写这篇文章就让我感到困惑。 是否可以仅使用一个以年为关键字并映射到节点的链接列表的哈希表,其中每个节点都包含电影名称,频率和类型?这样会更有效吗?

所以,如果我想更新蝙蝠侠的频率,我可以做map.get(2008),这将使链接列表的头部 然后做  while(tmp != null){ if(tmp.name == "the dark knight"){ temp.frequency++; }

1 个答案:

答案 0 :(得分:0)

因此,您考虑过使用年份的哈希图,流派的哈希图,名称到频率的哈希图。是否有意义?当然。这是解决问题的好方法吗?很有可能不会。如您所说,也有可能使用单个年份的主哈希图来收集流派名称频率元组(或许多语言(例如C,C ++,Java等)的结构)。通过集合,您想到了链表,但是您可以很好地使用向量或其他方法(链表通常是最差的一种数据结构)。但这并不一定会更有效率,也不一定是解决问题的更好方法,即使它可能更具可读性和可维护性。

我不会谈论不会影响时间复杂度的性能改进,因为您已经在注释中清楚地表明,这是针对只关心时间复杂度的考试(这很可惜,但无论如何)。另外,我假设这是您需要解决的唯一问题。

让我们看看如何改善您的想法。碰巧的是,两种解决方案的结合以及一项改进,在时间复杂度方面提供了最佳的解决方案,即O(k)。首先,请注意,每个电影名称仅与一个频率关联,并且每个频率仅与(可能)一个电影名称关联。而且,由于您要基于频率来检索电影名称,因此哈希图与线性的名称-频率对集合(例如矢量或链接列表)相比没有任何优势。然后,请注意,每年和每个流派都(独立地)与多部电影(每部电影都有名称和频率)相关联。因此,哈希图在这里占有一席之地:在给定的年份和类型下,类似哈希图的结构将在预期的恒定时间内为您提供相关的电影。

组合这两个结果,您将获得一个哈希表,其中以年份和流派作为键,并以名称-频率对的集合作为值。一种改进使得可以在k时间复杂度下检索给定年份和类型的O(k)最多流电影,这是一种排序:如果您的名称-频率对在每个集合中均按频率排序,则您可以简单地返回名字(或姓氏,取决于顺序)k

您可能会发现一个奇怪的细节是,哈希表同时使用年份和类型作为关键字。这是一个实现细节。您可以通过使用两个嵌套的哈希图来做到这一点,一个使用年份作为键,另一个使用类型,或者可以组合年份和类型并将这些对直接用作键。散列年份类型对实际上很简单。