Algorithm 用于检查静态数组是否不包含给定范围的元素的数据结构

Algorithm 用于检查静态数组是否不包含给定范围的元素的数据结构,algorithm,data-structures,big-o,Algorithm,Data Structures,Big O,我在数据结构课程的以下家庭作业问题上被困了几个小时: 我们给你一个静态的集合S(也就是说,S从不改变),它由n个来自{1,…,u}的整数组成 描述一个大小为O(n log u)的数据结构,它可以在O(1)时间内回答以下查询: Empty(i,j)-当且仅当S中没有介于i和j之间的元素(其中i和j是{1,…,u}中的整数)时,返回TRUE 起初我想用y-fast-trie 使用y-fast-trie,我们可以实现O(n)空间和O(logu)查询(通过找到i的后继者并检查它是否大于j) 但是O(lo

我在数据结构课程的以下家庭作业问题上被困了几个小时:


我们给你一个静态的集合S(也就是说,S从不改变),它由n个来自{1,…,u}的整数组成

描述一个大小为O(n log u)的数据结构,它可以在O(1)时间内回答以下查询:

Empty(i,j)
-当且仅当S中没有介于i和j之间的元素(其中i和j是{1,…,u}中的整数)时,返回TRUE

起初我想用y-fast-trie

使用y-fast-trie,我们可以实现O(n)空间和O(logu)查询(通过找到i的后继者并检查它是否大于j)

但是O(logu)不是O(1)

然后我想也许我们可以对数组进行排序,并创建一个大小为n+1的数组,该数组不在数组中,然后在查询中,我们将检查[I,j]是否是其中一个范围的子范围,但我没有想到任何使用O(nlogu)空间的方法,并且可以在O(1)中回答查询


我不知道如何解决这个问题,我觉得我甚至还没有接近解决方案,任何帮助都很好。

考虑一个由

  • 一种数组
    A[1,…,u]
    ,其大小
    u
    ,如果
    i
    存在于S中,则
    A[i]=1
    ,否则
    A[i]=0
    。这个数组可以由O(n)中的set
    S
    构造

  • 一个大小为
    u
    的数组
    B[1,…,u]
    ,它存储
    A
    的累积和,即
    B[i]=A[1]+…+A[i]
    。对于所有
    i>1
    ,可以使用关系
    B[i]=B[i-1]+A[i]
    A
    以O(u)为单位构造该数组

  • 返回所需布尔查询的函数
    空(i,j)
    。如果
    i==1
    ,则定义
    count=B[j]
    ,否则取
    count=B[j]-B[i-1]
    。请注意,
    count
    给出了S中位于范围
    [i,j]
    内的不同元素的数量。一旦我们有了
    count
    ,只需返回
    count==0
    。显然,每个查询都需要O(1)

编辑:正如注释中指出的,这个数据结构的大小是O(u),它与约束不匹配。但我希望它能给其他人一个大致的射击目标

  • 您尚未澄清给定的数字是否将被排序。如果没有,则对其进行排序,而将采用O(nlogn)

  • 求i的上界,比如x。求j的下界,比如y

  • 现在只需检查4个数字。索引x、x+1、y-1和y处的数字。如果给定数组的任何数字介于i和j之间,则返回true。否则返回false


  • 如果给定的集合/数组没有排序,那么在这种方法中,需要额外的O(nlogn)对其进行排序。内存需要O(n)。对于每个查询,都是O(1)

    我们可以创建一个S的x-fast-trie(占用O(nlogu)空间),并在每个节点中保存其子树中一片叶子的最大值和最小值。现在我们可以用它来回答O(1)中的空查询。像这样:

    空(i,j) 我们首先计算xor(i,j),现在这个数字中的前导零的数量将是前导位i和j共享的数量,让我们把这个数字标记为k。现在我们将取i的前k位(或j,因为它们相等),并检查x-fast-trie哈希表中是否有与这些位相等的节点。如果没有,我们将返回TRUE,因为i和j之间的任何数字也将具有相同的k个前导位,并且由于没有任何数字具有这些前导位,因此i和j之间没有任何数字。如果有,让我们将该节点标记为X

    如果X->right->minimum>j和X->left->maximum
    抱歉,英语不好

    这不是一个解决方案,但不可能写在评论中。有一个如何解决更具体任务的想法,这可能有助于解决问题中的一般任务

    具体任务相同,除了以下几点,u=1024。此外,它不是最终的解决方案,而是(针对特定任务的)一个草图

    数据结构创建:

  • 为U={1,…,U}-M=0000…..100001创建位掩码,其中Mᵥ = 1当你ᵥ ∊ S、 otherwice=0
  • 将位掩码M另存为“unsigned intgers 32”数组=G(32项)。G的每个项目包含M的32个项目
  • 合并整数H=位掩码,其中Hᵣ = 0当Gᵣ = 0,otherwice=1
  • 将G转换为G,即HashMap r到Gᵣ. G是G,但包含G的记录ᵣ != 只有0
  • 为了简单起见,以下伪代码中的图像使用除32位之外的8位

    Empty(i, j) {
       I = i / 32
       J = j / 32
    
       if I != J {
    


    “n个来自{1,…,u}的整数”我不明白,它是指[1,u]范围内的n个整数吗?如果没有重复,我假设(一个集合,而不是多集合),那么nO(1)?例如,
    i-j
    是一个恒定的时间,还是
    logu
    时间?@user58697拥有
    i-j
    除了
    O(1)
    之外的任何东西都会使它变得更难,所以让我们假设它是
    O(1)
    ;)如果你能达到规定的要求,我会感到惊讶。简洁压缩位向量的最佳结果可以在恒定的时间内完成查询,但只有当S与u相比不是太小时,它们才能满足空间要求。不过,它们支持比您更强的排名查询,所以可能。。。谷歌“琥珀”
           if P == 0: return true
    
           if P(I) == 0: return true
    
    
           if P(J) == 0: return true
    
       } else {
    
           if P(J=I) == 0: return true
       }
    
       return false
    }