简体   繁体   English

需要优化算法 - Arrays

[英]Optimize Algorithm Required- Arrays

We have an array A of integers of size N. Given another array B which contains indices, where size of B <= N and 0<=B[i]<=N-1 .我们有一个大小为 N 的整数数组 A。给定另一个包含索引的数组 B,其中size of B <= N0<=B[i]<=N-1大小。

Now we have to remove all elements from array A at position B[i] .现在我们必须从 position B[i]的数组 A 中删除所有元素。

So with deletion we mean we are also shifting elements in array A.因此,删除意味着我们也在移动数组 A 中的元素。

Can someone help me in reaching to O(n) solution for this problem?有人可以帮我解决这个问题的O(n)解决方案吗? And possibly O(1) space.可能还有 O(1) 空间。

The first solution that comes to my mind is, traversing the array B and deleting elements in A sequentially( including shifting) but it is O(n^2) .我想到的第一个解决方案是遍历数组 B 并顺序删除 A 中的元素(包括移位),但它是O(n^2)

Similar to iliaden's solution except you could do the removing of deleted elements in place.类似于 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;

note: a won't be shorter, but it avoid creating any more space.注意: a不会更短,但会避免创建更多空间。 'j' will have the number of valid entries in a 'j' 将具有a中的有效条目数

in O(n) space, you can do:在 O(n) 空间中,您可以执行以下操作:

  1. traverse array A deleting every element at b[i] (no shifting, O(n))遍历数组 A 删除 b[i] 处的每个元素(不移位,O(n))

  2. create a new array C, copy all the non-empty elements from A into C sequentially (also O(n))创建一个新数组 C,将所有非空元素从 A 依次复制到 C 中(也是 O(n))

  3. return array C or copy it back onto a cleared array A (O(n)).返回数组 C 或将其复制回已清除的数组 A (O(n))。 thus you get to do it in O(n) tim and O(n) space因此你可以在 O(n) 时间和 O(n) 空间中完成它

No marking, O(n) time, but also O(n) space, in pseudo-code:没有标记, 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

if you can assume b is sorted you can shift as you iterate (you can sort the b in O(n*log(n)) if not)如果您可以假设 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++;
    }
}

Two obvious solutions: sort B in reverse order before starting, so you always delete the highest index (and so never shift a deleted element), or iterate through B to create a bitmap of elements to delete (and then do those in the reverse order).两个明显的解决方案:在开始之前以相反的顺序对B进行排序,因此您始终删除最高索引(因此永远不要移动已删除的元素),或者遍历B以创建要删除的元素的 bitmap(然后以相反的顺序执行这些操作) )。 The first requires an additional O(lg n) step beforehand, and the second additional space.第一个需要预先额外的O(lg n)步骤,第二个额外的空间。 But I'm not sure there are any better alternatives.但我不确定是否有更好的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM