【问题标题】:Union of two sets given a certain ordering in O(n) time在 O(n) 时间内给定特定顺序的两个集合的并集
【发布时间】:2013-11-30 15:55:20
【问题描述】:

[注意:我希望这个问题可以在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,如果 i <= j,然后在其他一些集合 Y,对于相同的 i, j, i <= j

编辑:很抱歉,我错过了一些非常重要的内容,我在下面的其中一个 cmets 中已经介绍过 — 两个集合的交集不是空集合,即这两个集合具有共同的元素。

【问题讨论】:

  • 那些“其他属性”是否已知?您似乎可以使用这些属性将这些索引映射到已排序的线性集。
  • 鉴于它们是“集合”,我们是否可以假设这些项目在一个集合中是不同的(即没有项目可以出现多次)?
  • 是的,这些属性是已知的。您能解释一下“排序线性集的索引”是什么意思吗?
  • @Dukeling 是的,没错。
  • 如果两个集合不同怎么办? A = {1} , B = {2},联合应该是什么样的?

标签: algorithm union complexity-theory time-complexity


【解决方案1】:

将第一个集合中的每个项目插入到哈希表中。

遍历第二组中的每个项目,查找该值。

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

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

运行时间

预期为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 循环可能看起来很可疑,但请注意,该循环运行的每次迭代,我们都会增加 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、4、0 的?
  • 我唯一的问题是部分订单的“不确定性”。例如从示例集中删除零,联合不再是唯一的。否则解决方案是正确的。
  • 我理解您的担忧。但是这些集合会有共同的元素。所以 intersection(S1, S2) 不是空集。
  • @flippex17 我在回答中对此进行了扩展(这属于第二个项目符号中的“插入第一组中的所有项目...”)。
  • 好吧,我明白你做了什么,但我有点迷失了,因为你所使用的只是一个哈希表,它基本上提供了在O(1)时间搜索表中是否存在元素的能力.但是在第二种情况下,您处理的是不可能的索引;因此,这更像是一个O(n^2) 问题,而不是O(n)
【解决方案2】:

我们有两组有序的索引 A 和 B,它们由某个函数 f() 排序。所以我们知道f(A[i]) &lt; f(A[j]) iff i &lt; j,同样适用于集合B。

从这里,我们得到了到“排序”线性集的线性映射,从而简化为“排序集的并集问题”。

【讨论】:

  • 你能举个例子吗?我不相信这可以通过排序集的并集来解决(在 O(n) 中)。
  • 这本质上是您在解决方案中所做的,但利用了“已知”函数 f()。假设我们有一个不同整数 P 的数组,因此 A 是 偶数 个位置的元素的排序集合,B 是 奇数 个位置元素的集合。然后在“排序集并集”期间,条件将类似于 if (P[a[i]]
【解决方案3】:

这也没有最好的空间复杂度,但你可以试试:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2020-10-28
    • 2016-09-15
    • 1970-01-01
    相关资源
    最近更新 更多