题目 :
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?
解析:
这个题是,有这么一个数组,数组里的所有的元素都出现了三次(只有一个元素出现了一次),那么我们试着找出这个元素??
要求就是 :
1、时间复杂度要是 O(N);
2、空间复杂度为O(1);
这个题是有一定的难度的。。
我相信大部分的人都知道这个题 :::(single-number)
Given an array of integers, every element appears twice except for one. Find that single one.
一个数组里的数都出现两次 ,只有一个元素出现一次,找到这个数。。
我们是通过使用 位运算 ^ 两个相等的元素 异或的结果是 0 ; 找到这个只出现了一次的。。
在这个题中 ,我们就是利用的是 ^
使用的是一个数,来记录 每一个 bit 位出现的次数。
如果一个bit出现两次就归0,这种运算采用二进制底下的位操作^是很自然的;
只有一次的那个出现一次的数中的bit位 会被保存下来。。
那么这个题,是说的出现的了三次,那么我们就来,定义一下三进制下的异或操作,使得 每个bit 出现三次之后,就会为 0 ;
代码分析 :
class Solution {
public:
//给定一组整数,每个元素都出现了三次,除了一个。找到那个单一的。
//注意:
//你的算法应该有一个线性运行时复杂度。你能否在不使用额外内存的情况下实现它?
int singleNumber(int A[], int n)
{
int ones = 0;//记录只出现过1次的bits
int twos = 0;//记录只出现过2次的bits
int threes;
for(int i = 0; i < n; i++)
{
int data = A[i];
twos |= ones&data;//要在更新ones前面更新twos
ones ^= data;
threes = ones&twos;//ones和twos中都为1即出现了3次
ones &= ~threes;//抹去出现了3次的bits
twos &= ~threes;
}
return ones;
}
};
1、ones = 0;
ones表示的是出现 了一次的bit位;
2、ones ^= data;
这个操作 可以得到 将 出现了 一次的bit位数记录到 ones上。3、twos = 0;
twos记录出现了 两次的 bit位;4、twos |= ones&data;
ones & data 得到的结果,表示的出现了两个相同的bit位 ,也就是出现了两次的位;twos在 | 这个结果 ,,就可以将出现两了两次的位数 加到twos;
5、thress = ones& twos;
ones 出现了一次 ;twos出现了两次 。1&1 = 1;three表示的就是出现了三次的bit位数 。。
6、ones &= ~three; twos &= ~three;
~threes 取反出现了三次的bit位 ;ones 、twos &上这个结果可以减去出现已经出现三次的bit位。