【题目一】
一个整型数组里除了一个数字之外,其它的数字都出现了两次。请写程序找出这个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
【分析】
由于题目要求时间复杂度为O(n),所以先排序然后比较相邻数字是否相同的思路被排除。
空间复杂度是O(1),辅助空间被限制,所以hash表的思路也被排除。
注意这个数组的特殊性:其它数字都出现了两次,只有一个数出现了一次。
可以想到运用异或运算,任何一个数字 异或它自己都等于0。
如果我们从头到尾依次异或数组中的每一个数,那么最终的结果就是那个只出现一次的数字,因为其他出现两次的数字全部在异或中被抵消为0了(异或运算遵循交换分配率)。
【举例】
1 1 2 2 3
1 xor 1 xor 2 xor 2 xor 3 = 0 xor 0 xor 3 = 3
【代码】
#include<stdio.h>
int main()
{
int a[1000];
int result = 0;
int n;
scanf("%d",&n);
int num1;
for (int i = 0; i < n;i++)
{
scanf("%d",&a[i]);
result ^= a[i];
}
num1=result;
printf("%d\n",num1);
return 0;
}
【题目二】
一组数中,有一个数出现两次,其他的数都出现一次 高效地找出这个数。要求时间复杂度是O(n),空间复杂度是O(1)。
【分析】
通过一次循环,既输入了a数组中的元素,而且用b的数组记录了这些元素的频率,只要大于1,则说明是我们要求的那个数。
【代码】
#include<stdio.h>
int main()
{
int a[1000];
int b[1000]={0};
int length;
scanf("%d",&length);
for(int i=0;i<length;i++)
{
scanf("%d",&a[i]);
b[a[i]]++;
if(b[a[i]]>1)
{
printf("%d\n",a[i]);
}
}
return 0;
}
【感悟】
虽然说这俩题感觉很像,但是思路却不一样,不能用相同的方法解决,所以在看到一个题的时候,不能妄下结论,做不出来的时候实当换一下思路!