问答题 如何把一个整型数组中重复的数字去掉
【正确答案】
【答案解析】方法一:也是最容易想到的,就是遍历数组中的每一个元素,将元素与它前面的已经遍历过的元素进行逐一比较,如果发现与前面的数字有重复,则去掉;如果没有重复,则继续遍历下一个元素。由于每一个元素都要与之前所有的元素进行比较,所以时间复杂度为O(n 2 )。
方法一中这种最原始的方法在n比较小时,效率低下的缺点并不明显,但当数组元素比较多时,效率就会非常低下,于是想到了方法二,将原数组的下标值存在一个辅助数组中(也就是说辅助数组为{0,1,2,3...});然后根据下标指向的值对辅助数组排序,对排序后的辅助数组去重(也是根据下标指向的值);之后再按下标本身的值对去重后的辅助数组排序;最后顺次读出剩下的各下标指向的值即可。
例如,原数组为{1,2,0,2,-1,999,3,999,88},则辅助数组为{0,1,2,3,4,5,6,7,8},对辅助数组按下标指向的值排序的结果为{4,2,0,1,3,6,8,5,7},对辅助数组按下标指向的值去重的结果为{4,2,0,1,6,8,5},对辅助数组按下标本身排序的结果为{0,1,2,4,5,6,8},最后得到的结果为{1,2,0,-1,999,3,88}。主要的时间在两次排序,所以时间复杂度为O(nlogn)。
方法二:首先通过快速排序,时间复杂度为O(nlogn);然后对排好序的数组经过一次遍历,将其重复元素通过交换;最终达到删除重复元素的目的。以数组a[5]={1,2,1,2,3}为例,经过快速排序后,数组序列变为{1,1,2,2,3},此时标记两个变量k=-0,i=1,此时(a[k]=a[0])=(a[1]=a[i]),于是执行i++,i变为2,(a[i]=a[2])!=(a[0]=a[k]),则执行k++;k变为1,a[1]=a[2]=2,然后执行i++;i变为3,继续执行,(a[i]=a[3])=(a[1]=a[k]),于是执行i++;i变为4,(a[i]=a[4])!=(a[1]=a[k]),则执行k++;k变为2,a[2]=a[4]=3,执行完毕,返回k的值,即去除重复数字后的数组长度为3。所以,总的时间复杂度为o(nlogn)。程序代码示例如下:
#include<stdio.h>
#include<stdlib.h>
int int_cmp(const void *a,const void *b)
{
const int *ia=(const int *)a;
const int *ib=(const int*)b;
return *ia -*ib;
}
int unique(int *array,int number)
{
int k=0;
for(int i=1;i<number;i++)
{
if(array[k]!=array[i])
{
array[k+1]=array[i];
k++;
}
}
return (k+1);
}
int Unique_QuickSortMethod(int *arr, int elements)
{
∥C语言自带的排序函数
qsort(arr,elements,sizeof(int),int_cmp);
return unique(arr,elements);
}
int main()
{
int array[5]={1,2,1,2,3};
int len=sizeof(array)/sizeof(array[0]);
int size=Unique_QuickSortMethod(array,len);
for(int i=0;i<size;i++)
printf("%d",array[i]);
printf("/n");
return 0;
}
程序输出结果:
123