找出数组中只出现一次的2个数字

来源:互联网 发布:网络麻将 编辑:程序博客网 时间:2024/05/23 19:16

题目:

 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。找出这两个数字

分析:

  1.首先将数组所有元素依次异或,因为相同的元素异或得到0,所以最终的答案就等于那2个唯一的元素num1^num2的值。

  2.因为a,b不同,所以异或得到的答案肯定是不等于0的,那么我们就找到a^b的二进制表示中第一个为1的位.假设为n位,那么num1和num2在这一位上必定是一个为1,一个为0.

  3.利用数组元素的第n位是否是1,将数组元素分为两组。

  4. 接着我们就可以用(1)中的num1^num2的值在每个分组中异或每一个元素,最终就可以得到那2个唯一的元素。

代码如下:

void find_num(int arr[], int  sz, int *num1, int * num2){assert(arr);int ret = 0;int i = 0;int pos = 0;int tmp = 0;*num1 = 0; *num2 = 0;for (i = 0; i < sz; i++){ret ^= arr[i];      }    //找到num1^num2的结果tmp = ret;while (ret){if ((ret & 1)==1) //找到一个为1的位{break;}ret = ret >> 1;   //  也可以  ret/=2;++pos;}for (i = 0; i < sz; i++){if ((arr[i] >> pos)&1)//找出position位为1数的数{*num1 ^= arr[i];}}*num2 = *num1^tmp;}
测试程序:

#include<stdio.h>#include<windows.h> #include<assert.h>int main(){int arr[] = { 1, 2, 3, 5, 1, 2, 3, 4, };int sz = sizeof(arr) / sizeof(arr[0]);int num1 = 0 ,num2 = 0;find_num(arr, sz, &num1, &num2);    //返回型参数printf("%d %d\n", num1, num2);system("pause");return 0;}
这里,对于二进制的思想,我们需要格外注意!!!




0 0
原创粉丝点击