何海涛:《剑指Offer:名企面试官精讲典型编程题》:九度OJ
题目描述:
8 2 4 3 6 3 2 5 5
4 6
思想:使用 异或 解决问题,一个数异或自己等于0,异或其他数!=0,如果是一个数那么好办,异或之后的结果就是我们要的,但是现在是连个数据,那么我们要想想怎么讲那个数据分开!首先:我们还是先将所有的数进行异或,得到一个结果不等于0哦,那么在二进制位上必有为1的位(因为那2个数不一样),我们可以任意选择一位,当然,我们习惯选择最高或者最低位!这一位为1,那么就意味着第一个数的此位置上为1 ,第二个数此位置上为0,或者反之,不然不可能异或==1!那么根据这一位的特性,将数组元素分成两部分!然后分别对这两部分进行再次异或得到两个数~^_^
代码AC:
#include <stdio.h> #include <stdlib.h> int find_first_1_bit( int res ) // 每次移位(>>1)后若不能%2 != 0 ,则找到 { int n = 0; // 从第0位开始 while( res ) { if( res % 2 == 1 ) { break; } else { res = res >> 1; n++; } } return n; } int judge_N_bit( int num, int N ) // N 从0开始 { return ( num & ( 1 << N ) ); // 取第N位 } int main() { long int n, i; int *num, res, N, t1, t2; while( scanf("%ld", &n) != EOF ) { num = ( int* )malloc( sizeof( int ) * n ); scanf("%d", &res); num[0] = res; for( i = 1; i < n; i++ ) { scanf("%d", &num[i]); res ^= num[i]; } // // 第一次出现1的位置! N = find_first_1_bit( res ); t1 = 0; t2 = 0; for( i = 0; i < n; i++ ) { if( judge_N_bit( num[i], N ) ) // 若第N位为1 { t2 ^= num[i]; } else // 为0 { t1 ^= num[i]; } } if( t1 < t2 ) { printf("%d %d\n", t1, t2); } else { printf("%d %d\n", t2, t1); } free( num ); } return 0; }