例:在{1 2 3 4 5 6 1 2 3 4}找出5和6
方法二:
设计思想:
1.分组原理
(1)将所有数字进行异或,相同数字异或为零,所以只会剩5^6,即为异或的结果xor_result
(2)异或的结果xor_result按位与1,找出xor_result的二进制是从第几位开始有数字1
(3)根据求出的1所在位置进行分组
例如:{1,2,3,4,5,6,1,2,3,4}中,xor_result=3,二进制为011,那么可以从第0位或者第1位作为分组标准进行分组
第0位:第一组:1,3,5,1,3 第二组:2,4,6,2,4
第1位:第一组:2,3,6,2,3 第二组:1,4,5,1,4
2.分组方式
(1)将数组中的元素与xor_result相与,把相与为0和1的数字放在两个组中
(2)对分别对两个组的元素再次异或,异或的结果就是只出现一次的数字
即:假设按照第0位分组
第一组:1^3^5^1^3=5
第二组:2^4^6^2^4=6
这样就能求出只出现一次的数字
优点与不足:
时间复杂度O(n),效率比方法一高
只能算出存在两个只出现一次的数字
方法一:
设计思想:
设计两层循环遍历数组中的每一个元素。
在内层循环中再次遍历数组,检查是否存在与当前元素相等的其他元素。
如果存在相同元素,跳出内层循环,返回外循环继续检查下一个元素。如果不存在,那么说明当前元素只出现了一次,打印该这个元素,并将标志位 flag
设置为1。
优点与不足:
数组中存在0个、1个或多个只出现一次的数字可以被找到/提示
时间复杂度O(n^2)
- void find_dog(int arr[], int length)
- {
- int i = 0;
- int xor_result = 0;
- int tmp = 0;
- int num1 = 0;
- int num2 = 0;
- for ( i = 0; i < length; i++)
- {
- xor_result ^= arr[i];
- }
- for ( i = 0; i < 32; i++)
- {
- if (((xor_result >> i) & 1) == 1)
- {
- tmp = i;
- break;
- }
- }
- for ( i = 0; i < length; i++)
- {
- if (((arr[i] >> tmp) & 1) == 1)
- {
- num1 ^= arr[i];
- }
- else
- {
- num2 ^= arr[i];
- }
- }
- printf("%d %d", num1, num2);
-
- 方法一
- //int i = 0;
- //int j = 0;
- //int flag = 0;//判断是否存在只出现一次的情况,0不存在,1存在
- //for ( i = 0; i < length ; i++)
- //{
- // for ( j = 0; j < length; j++)
- // {
- //
- // if (i != j && arr[i] == arr[j])
- // break;
- // }
- // if (j == length)
- // {
- // flag = 1;
- // printf("%d\n", arr[i]);
- // }
- //}
- //if (0 == flag)
- //{
- // printf("不存在只出现一次的数字!\n");
- //}
- }
- int main()
- {
- int arr[] = { 1,2,3,4,5,6,1,2,3,4 };
- int length = sizeof(arr) / sizeof(arr[0]);
- find_dog(arr, length);
- return 0;
- }