我们有一个数组,它是未分类的。我们知道范围是[0,n]。
我们希望删除重复项,但我们不能使用额外数组,并且必须以线性时间运行。
有什么想法吗?只是为了澄清,这不是作业!
答案 0 :(得分:8)
如果整数限制为0到n,则可以在数组中移动,按索引放置数字。每次更换一个数字时,取出以前的值并将其移动到应该的位置。例如,假设我们有一个大小为8的数组:
-----------------
|3|6|3|4|5|1|7|7|
-----------------
S
其中S是我们的起点,我们将使用C来跟踪下面的“当前”指数。 我们从索引0开始,并将3移动到3索引点,其中4是。在临时变量中保存4。
-----------------
|X|6|3|3|5|1|7|7| Saved 4
-----------------
S C
然后我们在索引4中加上4,保存了那里的原因,5。
-----------------
|X|6|3|3|4|1|7|7| Saved 5
-----------------
S C
继续前进
-----------------
|X|6|3|3|4|5|7|7| Saved 1
-----------------
S C
-----------------
|X|1|3|3|4|5|7|7| Saved 6
-----------------
S C
-----------------
|X|1|3|3|4|5|6|7| Saved 7
-----------------
S C
当我们尝试替换7时,我们会发现冲突,所以我们根本就不会放置它。然后我们从起始索引S继续,将其递增1:
-----------------
|X|1|3|3|4|5|6|7|
-----------------
S
1这里很好,3需要移动
-----------------
|X|1|X|3|4|5|6|7|
-----------------
S
但是3是重复的,所以我们把它扔掉并继续遍历数组的其余部分。
基本上,我们最多移动每个条目一次,并遍历整个数组。那是O(2n)= O(n)
答案 1 :(得分:3)
假设int a[n]
是[0,n-1]范围内的整数数组。请注意,这与所述问题略有不同,但我做出此假设以明确算法的工作原理。该算法可以修补以适用于[0,n]范围内的整数。
for (int i=0; i<n; i++)
{
if (a[i] != i)
{
j = a[i];
k = a[j];
a[j] = j; // Swap a[j] and a[i]
a[i] = k;
}
}
for (int i=0; i<n; i++)
{
if (a[i] == i)
{
printf("%d\n", i);
}
}
答案 2 :(得分:3)
void printRepeating(int arr[], int size)
{
int i;
printf("The repeating elements are: \n");
for(i = 0; i < size; i++)
{
if(arr[abs(arr[i])] >= 0)
arr[abs(arr[i])] = -arr[abs(arr[i])];
else
printf(" %d ", abs(arr[i]));
}
}
答案 3 :(得分:0)
答案 4 :(得分:0)
遍历数组assign array [array [i]] = -array [array [i]];如果不是消极的;如果它已经是负数然后它的副本,这将起作用,因为所有值都在0和n之内。
答案 5 :(得分:0)
扩展@Joel Lee的代码以完成。
#include <iostream>
void remove_duplicates(int *a, int size)
{
int i, j, k;
bool swap = true;
while(swap){
swap = false;
for (i=0; i<size; i++){
if(a[i] != i && a[i] != a[a[i]]){
j = a[i];
k = a[j];
a[i] = k;
a[j] = j;
swap = true;
}
}
}
}
int main()
{
int i;
//int array[8] = {3,6,3,4,5,1,7,7};
int array[8] = {7,4,6,3,5,4,6,2};
remove_duplicates(array, sizeof(array)/sizeof(int));
for (int i=0; i<8; i++)
if(array[i] == i)
std::cout << array[i] << " ";
return 0;
}
答案 6 :(得分:0)
我认为使用ES6只需几行就可以解决,将数组简化为一个对象,然后使用object.keys获得没有重复的数组。这可能需要更多的内存。我不确定。
我是这样做的:
var obj = array.reduce(function (acc, elem) {
acc[elem] = true;
return acc;
},{});
var uniqueArray = Object.keys(obj);
这具有对数组进行排序的额外好处(或缺点)。它也适用于字符串。