解法一 暴力 O(n^2)
双重循环遍历数组,记录不重复的数字。
#include<stdio.h>
#define N 20 //数据范围
int a[N];
int main(){
int n, i, ans = 0,j;
scanf("%d", &n);
for(i = 0; i < n; i++)
scanf("%d", &a[i]);
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
if(j != i && a[i] == a[j]){
break;
}
}
if(j == n)
ans++;
}
printf("%d", ans);
return 0;
}
解法二 排序 O(nlogn)
O(nlogn)排序,然后O(n)一次遍历记录重复数值
代码:
#include<stdio.h>
#define N 20
void quikeSort(int a[], int low, int high){
int lowFlag = low, highFlag = high;
int key = a[low];
if(low >= high)
return;
while(low < high){
while(low < high && a[high] >= key)
high--;
a[low] = a[high];
while(low < high && a[low] <= key)
low++;
a[high] = a[low];
}
a[low] = key;
quikeSort(a, lowFlag, high-1);
quikeSort(a, low+1, highFlag);
}
int main(){
int a[N], n, rep = 0;
int i = 0;
double buff = 0.1;//因为输入的数据是整数,所以不可能出现小数,初始化为一个不可能的值
scanf("%d", &n);
while(i < n)
scanf("%d", &a[i++]);
quikeSort(a, 0, n-1);
for(i= 0; i < n-1; i++){
if(a[i] == a[i+1]){
if(buff != a[i]){
buff = a[i];
rep++;
}
rep++;
}
}
printf("%d", n-rep);
return 0;
}
解法三 空间换时间 O(max(n,m))
设出现的所有数据大小不超过 A,m代表其中最大的数
开一个N大小的数组t[A]记录每个数据出现的次数,初始化为0, 读入一个数a就查看t[a]是否为0,是则t[a]++,否则记录重复数据rep++。
最后遍历一遍t数组,计算所有出现次数为1的数即可。这里遍历到t[m]就可以。
c实现:
#include<stdio.h>
#define N 20 //数据范围
#define MAX 21474836 //每个数的最大值
int a[N], t[MAX];
int main(){
int n, i, rep = 0, maxnum = -9875432;
scanf("%d", &n);
for(i = 0; i < n; i++){
scanf("%d", &a[i]);
if(a[i] > maxnum)
maxnum = a[i];
t[a[i]]++;
}
for(i = 0; i <= maxnum; i++){
if(t[i] != 1)
rep += t[i];
}
printf("%d", n - rep);
return 0;
}
缺点:
空间消耗很大。 如果输入数据中存在一个很大的数,中间的空间都是不必要的。PS:不知道为什么我的devc++如果想把数组开到整数最大值2147483647就会报错。