LeetCode:Single Number II
题目地址:here
题目大意:一个整数数组中,只有一个数出现一次,其余数都出现3次,在O(n)时间,O(1)空间内找到这个出现一次的数
对于”只有一个数出现一次,其余数出现2次“的情况,很简单,只要把数组中所有数异或的结果就是这个出现一次的数,leetcode上也有这个题目。
关于本题:我们用一个大小为32的数组cnt来记录:(int数据的每个二进制位1的出现次数)%3,程序中cnt[i]记录第i+1个二进制位。如果某个数出现了三次并且他的第i个二进制位为1,因为做了模3操作,那么该数对数组cnt[i-1]的贡献为0,那么遍历完整个输入数组后,cnt[i]存储的就是这个出现一次的数的第i+1个二进制位。
程序中对于数组中的负数,都取其绝对值,这对结果没有影响,只是cnt数组最后保存的是这个出现一次的数的绝对值的二进制位,因此同时还要通过记录原数据的符号位来确定这个只出现一次的数的正负
代码如下:
1 class Solution { 2 public: 3 int singleNumber(int A[], int n) 4 { 5 // Note: The Solution object is instantiated only once and is reused by each test case. 6 short cnt[32];//cut[i]表示A中第(i+1)个二进制位的1个数(结果对3求模) 7 short sign = 0;//用来确定single number的符号,0正1负 8 memset(cnt, 0, sizeof(short)*32); 9 for(int i = 0; i < n; i++) 10 { 11 int tmp = A[i]; 12 if(A[i] < 0) 13 { 14 tmp *= -1; 15 sign = (sign + 1) % 3; 16 } 17 for(int k = 0; k < 32; k++) 18 { 19 cnt[k] = (cnt[k] + (tmp & 0x00000001))%3; 20 tmp = tmp >> 1; 21 } 22 } 23 int res = 0, base = 1; 24 for(int i = 0; i < 32; i++) 25 { 26 res += (base*cnt[i]); 27 base <<= 1; 28 } 29 return sign == 0 ? res : res*-1; 30 } 31 };
【版权声明】转载请注明出处:http://www.cnblogs.com/TenosDoIt/p/3388170.html