Algorithm 输入的平均间隔数(单位:0..N)

Algorithm 输入的平均间隔数(单位:0..N),algorithm,combinatorics,setinterval,Algorithm,Combinatorics,Setinterval,在检查“查找此集合中应包含[0..N]的K个缺失数字”问题时,出现了这个问题 该问题的作者要求得到CS答案,而不是基于方程式的答案,他的建议是对输入进行排序,然后迭代以列出K个缺失的数字 虽然这对我来说很好,但也似乎很浪费。让我们举一个例子: N=200 <Li>K=2(我们将考虑K你的方法与提出的排序方法似乎是一个经典的折衷方案,它既便宜又昂贵。 我发现您的符号有点混乱,请允许我使用我自己的: 设S为集合。设n为集合中的项数:n=|S |。设max为集合中的最大数:max=max(S)。设k

在检查“查找此集合中应包含[0..N]的K个缺失数字”问题时,出现了这个问题


该问题的作者要求得到CS答案,而不是基于方程式的答案,他的建议是对输入进行排序,然后迭代以列出K个缺失的数字

虽然这对我来说很好,但也似乎很浪费。让我们举一个例子:

  • N=200

  • <Li>K=2(我们将考虑K

    你的方法与提出的排序方法似乎是一个经典的折衷方案,它既便宜又昂贵。 我发现您的符号有点混乱,请允许我使用我自己的:

    S
    为集合。设
    n
    为集合中的项数:
    n=|S |
    。设
    max
    为集合中的最大数:
    max=max(S)
    。设
    k
    为不在集合中的元素数:
    k={0,…,max}\S

    对于排序解决方案,我们可以非常便宜地使用哈希将所有
    n
    元素插入
    S
    。这将需要预期的
    O(n)
    。然后为了查找
    k
    缺少的元素,我们在
    O(nlogn)
    中对集合进行排序,然后确定
    O(n)
    中缺少的元素

    也就是说,添加
    n
    元素然后查找缺少的
    k
    元素的总成本需要
    O(n)+O(nlogn)+O(n)=O(nlogn)


    您建议使用另一种方法,将集合表示为
    S
    的密集子集列表。您将如何实现这种数据结构?我建议使用排序树(而不是列表)以便插入变得高效。因为插入新元素
    e
    时您必须做什么?我认为您必须:

  • 在树中找到可以添加
    e
    的潜在候选子集
  • 如果子集已包含
    e
    ,则无需执行任何操作
  • 如果一个子集包含
    e+1
    ,而另一个子集包含
    e-1
    ,则将这些子集合并在一起,并将
    e
    添加到结果中
  • 如果子集已包含
    e+1
    ,但
    S
    中不包含
    e-1
    ,则将
    e
    添加到该子集
  • 如果子集已包含
    e-1
    ,但
    e+1
    未包含在
    S
    中,请将
    e
    添加到该子集
  • 否则,创建一个仅包含元素
    e
    的新子集,并将其插入树中
  • 我们可以预期,找到上述操作所需的子集需要
    O(logn)
    。4.或5.的操作需要恒定的时间,如果我们将子集表示为整数对(我们只需减少下限或增加上限).3.和6.可能需要更改树结构,但我们预计最多需要
    O(logn)
    ,因此整个“插入”所需的时间不会超过
    O(logn)


    现在有了这样一个数据结构,我们可以通过按顺序遍历树并收集不在任何子集中的数字来轻松确定
    k
    缺失的数字。成本与树中的节点数成线性关系,这是
    我认为最好在数学中问它。stackexchange,这是一个组合问题answers而不是基于方程的答案?根本没有这回事。方程可以用计算方法来求解。@Lior:[讽刺的是]谢谢你,我不知道![讽刺的是]方程需要特定的数学知识,因为你首先需要知道你的系统是可解的,以及用什么属性来创建所述方程,所以这确实是一个特殊的解决方案(我个人很难想出这样的解决方案)如果你有一个更好的公式,我愿意改进这个问题……运行时复杂性确实是相同的O(n logn),但是原始解决方案有O(n)空间复杂性(就像你基于哈希的解决方案)因此,我想知道我的解决方案是否平均具有更好的空间复杂度。问题是,对于非常大的列表,在真正的计算机上,内存紧凑性会影响运行时,特别是当一个函数命中磁盘(太大)而另一个函数未命中时。