[英]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 <= N
和0<=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) 空间中,您可以执行以下操作:
traverse array A deleting every element at b[i] (no shifting, O(n))遍历数组 A 删除 b[i] 处的每个元素(不移位,O(n))
create a new array C, copy all the non-empty elements from A into C sequentially (also O(n))创建一个新数组 C,将所有非空元素从 A 依次复制到 C 中(也是 O(n))
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.