在O(n)时间内给出一定排序的两组联合

时间:2013-11-30 15:55:20

标签: algorithm union complexity-theory time-complexity

  

[注意:我希望在O(n)时间内解决此问题。如果没有,我正在寻找一个在O(n)时间内无法解决的证据。如果我得到证明,我将尝试实现一种新算法,以不同的方式达到这些有序集的并集。]

考虑集合:

(1, 4, 0, 6, 3)
(0, 5, 2, 6, 3)

结果应为:

(1, 4, 0, 5, 2, 6, 3)

请注意,排序集的联合问题很容易。这些也是有序集,但排序是由已解析这些索引的其他一些属性定义的。但是排序(无论它是什么)对两个集合都是有效的,即对于任何i, j ∈ Set X if i <= j,然后在其他Set Y中对于相同的i, j, i <= j

编辑:对不起,我遗漏了一些非常重要的内容,我在下面的一条评论中介绍过 - 两个集合的交集不是空集,即两个集合都有共同的元素。

3 个答案:

答案 0 :(得分:4)

将第一组中的每个项目插入哈希表。

浏览第二组中的每个项目,查找该值。

  • 如果未找到,请将该项目插入到结果集中。
  • 如果找到,请将我们插入的最后一项之间的第一组中的所有项目插入此值。

最后,将第一组中的所有剩余项目插入到结果集中。

运行时间

预计O(n)

旁注

在给出约束的情况下,联合不一定是唯一的。

例如(1) (2),结果集可以是(1, 2)(2, 1)

此答案将选择(2, 1)

实施说明

显然,循环遍历第一个集合以查找最后插入的项目不会产生O(n)算法。相反,我们必须将迭代器保留在第一个集合(而不是哈希表)中,然后我们可以简单地从迭代器的最后位置继续。

这是一些伪代码,假设两个集合都是数组(为简单起见):

for i = 0 to input1.length
   hashTable.insert(input1[i])

i = 0 // this will be our 'iterator' into the first set

for j = 0 to input2.length
   if hashTable.contains(input2[j])
      do
         output.append(input1[i])
         i++
      while input1[i] != input2[j]
   else
      output.append(input2[j])

while i < input.length
   output.append(input1[i])

for循环中的do-while-loop可能看起来很可疑,但请注意,该循环运行的每次迭代都会增加i,因此它可以运行总共input1.length次。

示例

输入:

(1, 4, 0, 6, 8, 3)
(0, 5, 2, 6, 3)

哈希表:(1, 4, 0, 6, 8, 3)

然后,完成第二组。

查找0,找到,然后将1, 4, 0插入到结果集中 (尚未插入第一组中的项目,因此从开始插入所有项目,直到我们获得0)。

查找5,未找到,请将5插入到结果集中。

查找2,未找到,请将2插入到结果集中。

查找6,找到,然后将6插入到结果集中 (从第一组插入的最后一项是0,因此只需要插入6

查找3,找到,然后将8, 3插入到结果集中 (从第一组插入的最后一项是6,因此请在6之后插入所有项目,直到我们获得3。)

输出:(1, 4, 0, 5, 2, 6, 8, 3)

答案 1 :(得分:1)

我们有两组有序的索引A和B,它们由一些函数f()排序。所以我们知道f(A[i]) < f(A[j]) iff i < j,并且对于集合B也是如此。

从这里开始,我们得到了一个线性映射到“排序”的线性集,从而简化为“排序集合并存在的问题”。

答案 2 :(得分:0)

这也没有最佳的空间复杂性,但您可以尝试:

a = [1,2,3,4,5]
b = [4,2,79,8]

union = {}

for each in a:
    union[each]=1
for each in b:
    union[each]=1

for each in union:
    print each,' ',

输出:

>>> 1   2   3   4   5   8   79