一尘不染

如何相交两个没有重复的整数数组?

algorithm

这是我用作编程练习的面试问题。

输入: 两个排序的整数数组A和B,其递增顺序且分别具有不同的大小N和M

输出: 一个升序排序的整数数组C,其中包含同时出现在A和B中的元素

约束: C中不允许重复

示例: 对于输入A = {3,6,8,9}和B = {4,5,6,9,10,11},输出应为C = {6,9}

谢谢大家的回答!总结起来,有两种主要方法可以解决此问题:

我最初的解决方案是保留两个指针,每个数组一个,在选择匹配元素的同时从左到右交替扫描数组。因此,当我们一个数组的当前元素大于第二个数组的元素时,我们将不断增加第二个数组的指针,直到找到当前的第一个数组元素或将其覆盖(找到一个更大的元素)为止。我将所有匹配项保存在一个单独的数组中,当我们到达输入数组之一的末尾时将返回该数组。

我们可以执行的另一种方法是线性扫描一个数组,同时使用二进制搜索在第二个数组中找到匹配项。如果我们扫描A并对其B个元素的N个元素中的每一个进行二进制搜索,则这将意味着O(N * log(M))时间(O(log(M))时间)。

我已经实现了这两种方法,并进行了实验以查看两者的比较方式(有关详细信息,请参见此处)。当M比N大70倍时(当N具有100万个元素时),二进制搜索方法似乎会获胜。


阅读 252

收藏
2020-07-28

共1个答案

一尘不染

从本质上讲,此问题减少为 联接 操作,然后为 过滤器 操作(删除重复项并仅保留内部匹配项)。

由于输入均已排序,因此可以通过合并连接(O(size(a)+
size(b)))有效地实现连接

过滤器
操作将是O(N),因为删除的连接进行排序,并输出复制所有你需要做的是检查,如果每个元素都和以前一样它的人。仅过滤内部匹配项很简单,您只需丢弃所有不匹配的元素(外部联接)。

并行处理(在连接和过滤器中)都有机会获得更好的性能。例如,Hadoop上的Apache
Pig
框架提供了合并联接的并行实现

在性能和复杂性(以及可维护性)之间存在明显的权衡。因此,我想说,一个采访问题的好答案确实需要考虑绩效要求。

  • 基于集合的比较-O(nlogn)-比较慢,非常简单,如果不存在性能问题,则使用。简单胜出。

  • 合并连接+过滤器-O(n)-快速,容易出现编码错误,如果性能存在问题,请使用。理想情况下,尝试利用现有库来执行此操作,或者在适当的情况下甚至使用数据库。

  • 并行实施-O(n / p)-非常快,需要其他基础设施,如果体积非常大且预计会增长,则使用该基础设施是主要的性能瓶颈。

(还请注意,问题 intersectSortedArrays
中的函数本质上是修改后的合并联接,该过程在联接期间进行过滤。此后,尽管内存占用量略有增加,也可以进行过滤而不会造成性能损失)。

最后的想法。

实际上,我怀疑大多数现代商业RDBMS在其连接的实现中都提供线程并行性,因此Hadoop版本提供的是机器级并行性(分布)。从设计的角度来看,对于这个问题,也许一个好的简单解决方案是将数据放在数据库中,在A和B上建立索引(有效地对数据进行排序)并使用SQL内部联接。

2020-07-28