Это можно сделать за один проход с помощью алгоритма O (N log N) и без дополнительной памяти.
Перейти от элемента a[1]
к a[N]
. На каждом этапе i
все элементы слева от a[i]
содержат отсортированную кучу элементов от a[0]
до a[j]
. Между тем, второй индекс j
, изначально 0, отслеживает размер кучи.
Изучите a[i]
и вставьте его в кучу, которая теперь занимает элементы с a[0]
по a[j+1]
. Поскольку элемент вставлен, если обнаружен дублирующий элемент a[k]
, имеющий то же значение, не вставляйте a[i]
в кучу (то есть, отбрасывайте его); в противном случае вставьте его в кучу, которая теперь увеличивается на один элемент и теперь содержит от a[0]
до a[j+1]
и увеличивает j
.
Продолжайте в том же духе, увеличивая i
до тех пор, пока все элементы массива не будут проверены и вставлены в кучу, которая в итоге занимает от a[0]
до a[j]
. j
- это индекс последнего элемента кучи, и куча содержит только уникальные значения элементов.
int algorithm(int[] a, int n)
{
int i, j;
for (j = 0, i = 1; i < n; i++)
{
// Insert a[i] into the heap a[0...j]
if (heapInsert(a, j, a[i]))
j++;
}
return j;
}
bool heapInsert(a[], int n, int val)
{
// Insert val into heap a[0...n]
...code omitted for brevity...
if (duplicate element a[k] == val)
return false;
a[k] = val;
return true;
}
Глядя на пример, это не совсем то, о чем просили, так как результирующий массив сохраняет исходный порядок элементов. Но если это требование ослаблено, алгоритм, приведенный выше, должен сработать.