在元素重复三次的数组中查找只出现一次的元素
问题
给定一个数组,它里面除了一个元素外,其他元素都重复了三次,要求空间复杂读为 O ( 1 ) O(1) O(1),时间复杂度为 O ( n ) O(n) O(n),查询只出现一次的元素。
分析
不能进行排序查找,排序时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),所以必须 O ( n ) O(n) O(n)遍历数组得出结果。
我们考虑位运算。除了一个元素之外,其他元素重复了三次。将每个数字转换为二进制,如果某个比特位的值是1,那么该比特位上的1至少出现了3次。原问题可通过设计一个算法,在某个比特位上检测到出现三次1就清零。那就可以在 O ( n ) O(n) O(n)时间复杂度内得到只出现一次的元素。
代码
public int oneTimeElement(int[] arr){
// 记录只出现1次的比特位和出现两次的比特位
int one = 0;
int two = 0;
for (int i = 0; i < arr.length; i++){
int element = arr[i];
int T = two;
int O = one;
two = T ^ (T & element); //去除出现过三次的比特位1
element = element ^ (T & element); //去除出现过三次的比特位1
two = two | (element & O); //设置出现两次的比特位1
one = one ^ element; //设置只出现一次的比特位1
}
return one;
}