剑指 Offer 03. 数组中重复的数字

剑指 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;

  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

  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的指向就会混乱,这是极其危险的,所以编译器会禁止。

  正确的写法如下:

  1. L使用strcpy,不要忘了加头文件<string.h>
strcpy(a,"str");
  1. 在定义的时候赋值:
char a[5]="str"
char b[5]={"s","t","r"};

上一篇:AcWing 3250. 通信网络 两次bfs


下一篇:免费馅饼 HDU - 1176