优化所需算法-数组

Optimize Algorithm Required- Arrays

本文关键字:数组 算法 优化      更新时间:2023-10-16

我们有一个大小为N的整数数组A。给定另一个包含索引的数组B,其中size of B <= N0<=B[i]<=N-1

现在,我们必须从位于B[i]位置的数组A中移除所有元素。

因此,删除意味着我们也在移动数组A中的元素。

有人能帮我找到这个问题的O(n)解决方案吗?可能还有O(1)空间。

我想到的第一个解决方案是,遍历数组B并按顺序删除A中的元素(包括移位),但它是O(n^2)

类似于iliaden的解决方案,只是您可以就地删除已删除的元素。

int[] a = 
int[] b = 
int nullValue = 
for(int i: b) a[i] = nullValue;
int j=0;
for(int i=0; i < a.length; i++) {
    if(a[i] != nullValue)
       a[j++] = a[i];
}
// to clear the rest of the array, if required.
for(;j<a.length;j++)
   a[j] = nullValue;

注意:a不会更短,但它避免了产生更多的空间j’将具有a 中的有效条目数

在O(n)空间中,您可以执行:

  1. 遍历数组A删除间隔元素在b[i](无移位,O(n))

  2. 创建一个新的数组C,复制所有非空元素从A按顺序(也称为O(n))

  3. 返回数组C或将其复制回到被清除的阵列a(O(n))上。这样你就可以在O(n)tim中完成它和O(n)空间

无标记,O(n)时间,也有O(n)空间,伪代码:

// create a boolean array indicating which elements are to be deleted
D = new boolean[N]
fill(D, false)
for (b in B) {
  D[b] = true
}
// compact `A in place
src = 0
dest = 0
while (src < N) {
  if (!D[src]) {
    A[dest++] = A[src]
  }
  src++
}
new_N = dest

如果你可以假设b是排序的,那么你可以在迭代时移位(如果不是,你可以在O(n*log(n))中对b进行排序

int[] b;
int[] a;
int first=0,bInd=0;
for(int i = 0;i<a.length;i++){
    if(bInd>=b.length || b[bInd]!=i){
        a[first]=a[i];
        first++;
    }else{
        bInd++;
    }
}

两个显而易见的解决方案:在启动前按相反的顺序对B进行排序,因此总是删除最高的索引(因此从不移动已删除的元素),或者迭代CCD_ 11以创建要删除的元素的位图(以及然后按相反的顺序进行)。第一个需要额外的O(lg n)步骤和第二附加空间。但我不是当然还有更好的选择。