昨天一下子做了几道简单题,本来想再做多一点,被这道Single Number II 困住了,题目描述如下:
Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
这道题跟single Number那道题有点像,于是我又想着是不是应该也是按位异或之类的,之前的异或,那我就同或,发现不对,然后又试了很多其它的组合,感觉像是在做数电题目,什么与门、或门、与非门、或非门等等,叫上室友wdc来一起想,结果还是没有想出来。难道这道题没有像前面那道题那样直接一个异或就能解决的方法。于是偷瞄了一下网上的解法,发现网上的解法都是那固定的两种。难道大家都是看答案的?!还是也想到同样的方法,牛!果然被虐惨了。
解题思路大致上就说定义一个int长度大小的数组,存放对应原数组中每个数的每个位的1的个数,当是3的倍数时,变成0,那么剩下来的就是那个单独的数了。一开始又想着这种想法挺不错的喔。但是题目不是要求线性时间复杂度吗?两个for循环不就是n的平方啦。后面看一下某人的解释,O(32n)就是线性的,跟O(n)一样。对哦。唉,那么简单的东西都忘了,真的是,唉。。。但是另外一个地方,申请了个int大小的数组,跟题目中的那个“without using extra memory”会不会有矛盾呢?好像申请常量空间是可以的。
我的代码如下:
int singleNumber2(int A[], int n)
{
if (1 == n)
{
return A[0];
}
//建立一个sizeof(int)大小的数组,用于存放每个位1的个数
const int int_size = sizeof(int)*8;
int count[int_size] = {0};
int bit = 1; //用于移位的变量
int single = 0; //结果数
for (int i = 0; i < int_size; i++)
{
count[i] = 0;
for(int j = 0; j < n; j++)
{
//判断数组元素的某一位是什么,并将其加到count数组中
count[i] += (0 == (A[j] & bit))?0:1;
//如果count元素等于3,那么将其置零
if(3 == count[i])
{
count[i] = 0;
}
}
//移位变量左移一位
bit = bit<<1;
//计数变量左移该变量对应的位后与结果数相或
single |= count[i]<<i;
}
return single;
}
代码里面的注释已经写得比较清晰了。就不多说了。只是有点不甘心,是看了解题的思路才写出程序来。