Reputation: 6281
I have items in the centre of an array and I want to move them to the front of this array. For example:
array[8] = {10, 38, 38, 0, 8, 39, 10, 22}
and I have an index array
index[6] = {0, 3, 4, 6, 7, 1}
and I want to move these 6 items to the front of the array
result[8] = {10, 0, 8, 10, 22, 38, 38, 39}
Actually the order doesn't matter, just make sure the item whose index is in the index array should always before the item whose index is not in the index array.
Can anyone give me a fast algorithm? Actually this is one step in an KNN problem, the data array could be very large. The algorithm should run as fast as possible and the extra space needed should be as small as possible. It is better if you can give me CUDA implementation.
Update: Compare to the data array, the size of the index array is very small. In my case, it is only about 200.
Update: Please note that the size of the data array could be very very very large! It goes to 1M, 10M even higher(The data array is loaded to GPU memory which is quite limited). Any algorithm needs a temp array which has the same size with data array is not acceptable.
Upvotes: 1
Views: 1598
Reputation: 13
You can modify insertion sort to solve your problem which will eventually give you O(n^2) time complexity. But if you want to keep run time in order of N then you can use following approach.
Here we can use index array as auxiliary space as follows :
store all actual values instead of indexes in index table(array) and replace the value array with negative/non accepting value.
[ -1, -1, 38, -1, -1, 39, -1, -1 ]
[ 10, 0, 8, 10, 22, 38 ]
complexity in this operation is O(n)
shift all the remaining at last which will take O(n) time complexity.
[ -1, -1, -1, -1, -1, -1, 38, 39 ]
[ 10, 0, 8, 10, 22, 38 ]
not put the element from index array to value array.
[ 10, 0, 8, 10, 22, 38, 38, 39 ]
[ 10, 0, 8, 10, 22, 38 ]
time complexity for this operation is O(n)
Total run time complexity for this approach : O(n)
Here in this approach you are not able to preserve your index array. While you can preserve it using O(index array size) space complexity OR with the condition that value array does not contain any non negative values then while keeping -1/non accepting value in it you can use storing index with -ve and in third step you can recover your index array as it is.
Upvotes: 0
Reputation: 11284
Sort the index
array in increasing order, this step will make sure that we will not make any unnecessary swap.
Starting from 0 to n - 1 (n is the length of array index
), swap the ith
element in the array with index[i]th
element.
Pseudo Code
sort(index);
for(int i = 0; i < index.length; i++){
swap(array, i , index[i]);
}
If you don't want to sort index
, we can always find the smallest element in the index
array which is not at the beginning of the array. (as the size of index is small)
Use an boolean used
to mark which position in the array index
is already put at the correct position.
Pseudocode:
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);
}
Upvotes: 1
Reputation: 259
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;
}
}
Upvotes: 0