剑指 Offer 03. 数组中重复的数字
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
限制:
2 <= n <= 100000
代码:
int findRepeatNumber(int* nums, int numsSize){
int a[numsSize];
memset(a, 0, sizeof(a));
for(int i = 0;i<numsSize;i++)
{
a[nums[i]]++;
if(a[nums[i]]>=2)
{
return nums[i];
}
}
return -1;
}
这里做几点解释:
- 在c中,用变量声明数组时,只能是先声明,再赋值,不能同时赋值;
- 给数组赋统一的值时,可以使用memset()函数;这里我想引用一位前辈在博文中写的话:“只建议初学者使用 memset 赋 0 或 -1。 因为memset使用的是按字节赋值,即对每个字节赋同样的值,这样组成 int 型的 4 个字节就会被赋成相同的值。而由于 0 的二进制补码为全 0,-1 的二进制补码为全 1 ,不容易弄错。如果要对数组赋其他数字(例如1),那么请使用 fill 函数(但 memset 的执行速度快)。”
- memset函数的格式是:
memeset(数组名, 值,sizeof(数组名));
- 使用 memset 需要在程序开头添加 string.h 头文件。
- 上边代码的思路是从《啊哈算法》中学到的,也顺便推荐一下这本书。
下面是那位前辈在博客中举得例子,也充分说明了为什么尽量赋初值为0或者-1;
- 将初值赋为0或者-1
#include <stdio.h>
#include <string.h>
int main() {
int a[5] = {1, 2, 3, 4, 5};
// 赋初值 0
memset(a, 0, sizeof(a));
for(int i = 0; i < 5; i++) {
printf("%d ", a[i]);
}
printf("\n");
// 赋初值 -1
memset(a, -1, sizeof(a));
for(int i = 0; i < 5; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
输出结果为:
0 0 0 0 0
-1 -1 -1 -1 -1
- 但如果赋初值为其他值:
#include <stdio.h>
#include <string.h>
int main() {
int a[5] = {1, 2, 3, 4, 5};
// 赋初值 1
memset(a, 1, sizeof(a));
for(int i = 0; i < 5; i++) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
此时输出结果为:
16843009 16843009 16843009 16843009 16843009
另外在做这道题的时候,刷到了一篇博客,其中提到了字符数组的赋值问题:
char a[5];
a="str";
注意这样是不行的,a作为数组名表示数组在内存中的地址,a指向的是地址,5个字符所占的地址,但此时又把str赋值给它,a的指向就会混乱,这是极其危险的,所以编译器会禁止。
正确的写法如下:
- L使用strcpy,不要忘了加头文件<string.h>
strcpy(a,"str");
- 在定义的时候赋值:
char a[5]="str"
char b[5]={"s","t","r"};