找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
原题:
数组中的重复数字
或直转到:
https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
我的题解:
int findRepeatNumber(int* nums, int numsSize){
int mynums[numsSize];
int i,j;
for(i=0;i<numsSize;i++){
mynums[i]=0;
}
for(i=0;i<numsSize;i++){
mynums[nums[i]]++;
}//for
for(j=0;j<numsSize;j++){
if(mynums[j]>1){
break;
}
}
//以下代码块为耻辱代码块
/*int i,j;
int temp=*nums;
int repeatNum;
if(numsSize<50000){
for(i=0;i<numsSize;i++){
for(j=0;j<numsSize-i;j++){
if(*(nums+i)>*(nums+j)){
temp=*(nums+i);
*(nums+i)=*(nums+j);
*(nums+j)=temp;
}
}
}
}
for(i=0;i<numsSize;i++){
if(*(nums+i)!=i){
repeatNum=*(nums+i);
}
}
*/
return j;
}//Func_findRepeatNumber
真是一道看似简答实则暗藏杀鸡的题
-
我原来的想法:
100000个数字,咱cpu不至于这么拉吧。我先来一个泡沫排序,然后相邻比较,perfect。结果超时,沃日。前方泡沫排序时间复杂度太高了,就算相邻比较消耗不了 多少,整体还是超时了。那我就思考怎样在这种情况下不超时呢?我先尝试了前五万用泡沫排序后五万直接比较,后全部用比较,真是纯纯的傻,时间复杂度和泡沫排序一个样。我真的傻了,想不出来怎么写。 -
偷窥了一下别的大佬想法
先创建一个数组,全部以0初始化,遍历一般原来存储数字的数组。由于题干给出限定项,数组的大小同时也限制了数组元素的大小。我们可以把原来数组中的元素当做新创建数组的角标,要是有对应角标,则进行++,最后检查超过1的数组内空间,由于数组是线性的,肯定也是哪个最靠近num[0]哪个就return。时间复杂度为n,太妙了。不需要进行排序,这个好像和字典好像,真后悔当初没好好学C#,直接上手了unity
好兄弟,要回宿舍了,教学楼要关门了,等我躺床山再补一个别的大神思路。22:31 -
大佬码中我想不到的hash
int findRepeatNumber(int* nums, int numsSize){
int *hash = (int *)calloc(numsSize, sizeof(int));
for(int i = 0; i < numsSize; i++){
if(hash[nums[i]] == 1){
return nums[i];
} else {
hash[nums[i]]++;
}
}
return -1;
}
我发现整体思路和上一个一样,不一样的是这个调用了动态内存管理而不是直接创建同大小数组。根据calloc特性可以知道创建后数组内都要进行初始化。整型数组初始化结果为0.
也就是说同样创建了一个大小为numsSize的数组,思路是一样的,就是创建数组的方式不一样。可见我写的程序就是利用创建数组实现了哈希表,这个则是直接利用calloc进行创建。
其实还有一个好处,就是如果题例若没有出现重复项这个直接就可以判断,而我写的方法还要加一段代码。
坏处就是貌似malloc的内存消耗比较大,只是代码量小罢了,也不失一种方法。