我有一个数组中心的项目,我想将它们移动到这个数组的前面。例如:
array[8] = {10, 38, 38, 0, 8, 39, 10, 22}
我有一个索引数组
index[6] = {0, 3, 4, 6, 7, 1}
我希望将这6个项目移到数组的前面
result[8] = {10, 0, 8, 10, 22, 38, 38, 39}
实际上订单并不重要,只要确保索引在索引数组中的项应该总是在索引不在索引数组中的项之前。
有人能给我一个快速的算法吗?实际上这是KNN问题的一个步骤,数据阵列可能非常大。算法应该尽可能快地运行,并且所需的额外空间应该尽可能小。如果你能给我CUDA实现它会更好。
更新:与数据数组相比,索引数组的大小非常小。就我而言,它只有大约200个。
更新:请注意,数据阵列的大小可能非常大!它达到1M,甚至更高10M(数据阵列被加载到GPU内存,这是非常有限的)。任何算法都需要一个与数据数组大小相同的临时数组是不可接受的。
答案 0 :(得分:1)
按递增顺序对index
数组进行排序,此步骤将确保我们不会进行任何不必要的交换。
从0开始到n - 1(n是数组index
的长度),用ith
元素交换数组中的index[i]th
元素。
伪代码
sort(index);
for(int i = 0; i < index.length; i++){
swap(array, i , index[i]);
}
如果您不想排序 index
,我们总能找到index
数组中不在数组开头的最小元素。 (因为索引的大小很小)
使用布尔值used
标记数组index
中的哪个位置已放置在正确的位置。
伪代码:
bool []used = //
for(int i = 0; i < index.length; i++){
int nxt = -1;
for(int j = 0; j < index.length; j++){
if(!used[j]){
if(nxt == -1 || index[j] < index[nxt]){
nxt = j;
}
}
}
used[nxt] = true;
swap(array, i, nxt);
}
答案 1 :(得分:0)
const int ARRAY_SIZE = sizeof(array) / sizeof(array[0]);
const int INDEX_SIZE = sizeof(index) / sizeof(index[0]);
bool used[ARRAY_SIZE] = {};
for (int i = 0; i < INDEX_SIZE; ++i)
{
int id = index[i];
result[i] = array[id];
used[id] = 1;
}
for (int i = 0, id = INDEX_SIZE; i < ARRAY_SIZE; ++i)
{
if (!used[i])
{
result[id] = array[i];
++id;
}
}
答案 2 :(得分:0)
您可以修改插入排序来解决您的问题,最终会给您带来O(n ^ 2)时间复杂度。 但是如果你想按N的顺序保持运行时间,那么你可以使用以下方法。
这里我们可以使用索引数组作为辅助空间,如下所示:
在索引表(数组)中存储所有实际值而不是索引,并将值数组替换为负/非接受值。
[ -1, -1, 38, -1, -1, 39, -1, -1 ]
[ 10, 0, 8, 10, 22, 38 ]
此操作的复杂性为O(n)
最后移动所有剩余的,这将花费O(n)时间复杂度。
[ -1, -1, -1, -1, -1, -1, 38, 39 ]
[ 10, 0, 8, 10, 22, 38 ]
不将元素从索引数组放到值数组。
[ 10, 0, 8, 10, 22, 38, 38, 39 ]
[ 10, 0, 8, 10, 22, 38 ]
此操作的时间复杂度为O(n)
此方法的总运行时复杂度:O(n)
在这种方法中,您无法保留索引数组。虽然您可以使用O(索引数组大小)空间复杂度 OR 保留它,条件是值数组不包含任何非负值,然后保持-1 /非接受值,您可以使用存储使用-ve索引,在第三步中,您可以按原样恢复索引数组。