哈哈,好多分析
本题的思路如最后一个功能函数所示:
由算法思路可得:总共的时间复杂度是O(n)
因为,第一步,数组全部遍历一边,相等的数位运算异或后为0,剩下两个不同的异或后不为0
功能函数1:要是异或后不为零的数,寻找第一个不为零的那一位
功能函数2:寻找某一位为0,以及为1的数
两个功能函数写完后,继续第二遍遍历,用功能2函数,把某一位为1的数,和*num1做异或,最后能得到一个只出现一次的数,同理,得到另一个出现一次的数,即就是,把某一位为0的数,和*num2做异或,可得到另一个出现一次的数
整体思想是,运用了异或可得到只出现一次的不同的数,然后将要求得的两个数分在两个数组里,但是这里并没有重新赋值新数组的过程,而直接对某一类的数进行异或,并且分类过程可以把出现两次的数,分为一类,显而易见
啰里啰嗦的感觉,还是想分析一下,为啥就能把两个数刚好分开来,因为,yihuo得到的是最后两个不同的数异或的结果,
寻找第一位为1的位,说明这两个数这一位是不同的,所以根据0和1就能把两个数分开来
class Solution {
public:
//对于位运算更加熟悉一点
int FindFirstBitIs1(int number)
{
int index = 0;
while(!(number&1)){
number=number>>1;
index++;
}
return index;
}
bool IsBit1(int data, int index)
{
//借助移位,位与的方式来判断某位的情况,这种使用方法需要好好熟悉一下
data=data>>index;//右移index位
return (data&1);//查看右移后第一位是否为1
}
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int len=data.size();
if(len<2)
return;
int yihuo = 0;
for(int i = 0; i <len; i++){
yihuo ^=data[i];
}
unsigned int indexof1 = FindFirstBitIs1(yihuo);
*num1=*num2=0;
for(int i = 0; i<len; i++){
if(IsBit1(data[i],indexof1))
*num1^=data[i];
else *num2^=data[i];
}
}
};