【问题标题】:How can two or more lists be traversed in O(N)如何在 O(N) 中遍历两个或多个列表
【发布时间】:2015-09-24 22:37:54
【问题描述】:

我有一个对我来说似乎不可能的问题。我有 2+ 个数组,我必须比较它们的共同值。我应该在 O(N) 比较中这样做,但想不出办法。特别是 (k-1)N 次比较,其中 k 是数组的数量。我已经缩小了如何获取多个数组并将它们合并到一个数组中的范围。我已经知道最小的数组是限制因素,所以如果我排序,我可以保存最多的比较。在盯着我的屏幕看了半天之后,我什至想出了一种方法来线性地做到这一点,如果我打折任何重复项,但我必须保留重复项所以,据我所知,为了比较你需要的任何数组至少 2 个 for 循环是 O(N^2) 不是吗?我也不允许散列任何东西。

例如,如果我有 {1,3,4,3,4,5} 作为主人,{1,1,3,5,9,3,7} 和 {3,5,8,4, 0,3,2} 作为要比较的数组,我需要有一个 {3,3,5} 的决赛,因为我无法摆脱任何重复。

我不想让任何人写代码,我只需要知道我首先应该做什么。

【问题讨论】:

  • 如果数组未排序,我也觉得不可能。
  • 我可以对它们进行排序。如果是的话,你有什么办法吗??
  • 不过,对它们进行排序需要的不仅仅是 O(n) 次比较。
  • 允许在比较它们的方法之外进行排序。只有将它们与实际最终数组进行比较的方法需要 O(N)。
  • @Read_My_Feels991:如果我的方法有效,请告诉我。我已经更新了。

标签: java arrays algorithm performance comparison


【解决方案1】:

使用整数数组。获取您的第一个列表,对于每个元素,将该索引处的值设置为1。因此,如果第一个元素是 3,则将 1 放入数组 [3] 中。现在,我们知道 3 出现在第一个列表中。输入1 将帮助您区分较早列表中出现的 3 与当前列表中重复的 3。

  1. 遍历所有其他 k-1 个列表
  2. 对于每个元素,检查数组中该索引的值
  3. 如果值为0,则设置为该列表编号
  4. 如果该值是小于此列表编号的数字,则此数字是重复的,并且已出现在之前的列表中。
  5. 如果此数字等于此列表索引,则表示此数字已出现在此列表中,但未出现在以前的列表中,因此还不是重复的。
  6. 您获得的重复号码,请将它们添加到另一个列表中。
  7. 完成所有迭代

最后打印副本。


原来的错误答案

  1. 创建HashSet<int>
  2. 从 master 获取所有值并添加到它 - O(master list count)
  3. 现在只需遍历第一个和第二个数组,看看它们的元素是否在那个 HashSet 中 - O(每个列表计数)

【讨论】:

  • 问题明确指出“我也不允许散列任何东西。”
  • 您正在使用索引,这本质上是一种自己动手的散列方法。如果原始值都限制在一个小的整数范围内,这将是一个很好的方法。很明显,一位试图教授合并方法的讲师向 OP 提出了一个问题。
  • @MikeDunlavey:我不知道这种合并方法可以帮助在 O(N) 的链表中找到重复项。你能给我一些链接吗?
  • @MikeDunlavey:我知道如果我们要处理的数字范围较小,这种方法会更好,但我希望尽可能保持解决方案的通用性。
  • 合并是一种基本模式。假设您有两副独立的牌,每副牌都已经在其内部进行了排序。你查看每一副牌的最上面的牌。如果一个小于另一个,你丢弃它,而不是另一个。如果两者相同,则您有火柴,因此您将两者都放在火柴堆上。这花费的时间不超过卡的数量。如果您保留所有卡片,则对结果进行排序。 (如果你递归地做,你有合并排序算法。(我最喜欢的))
【解决方案2】:

如果列表已排序,那么执行以下操作相对简单:

List<Integer> intersection = new ArrayList<>();
int i = 0;
int j = 0;
while (i < list1.size() && j < list2.size()) {
  int a = list1.get(i);
  int b = list2.get(j);
  if (a < b) {
    i++;
  } else if (b < a) {
    j++;
  } else { // a == b
    intersection.add(a);
    i++;
    j++;
  }
}

在循环的每一次迭代中,i + j的数量至少增加1,并且在i + j &gt;= list1.size() + list2.size()时保证循环完成,所以整个事情最多做O(list1.size() + list2 .size()) 比较。

【讨论】:

  • a &lt; bb &gt; a 条件相同。
  • 诀窍是如何在不给出代码的情况下回答它,因为它很可能是一道作业题。
猜你喜欢
  • 1970-01-01
  • 2010-11-15
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 2010-12-12
相关资源
最近更新 更多