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 类似
思路1:先排序,后寻找是否三个连续值相同,不同则return这个值。用到Arrays.sort函数,时间复杂度不符合要求。
Solution1:
public class Solution {
public int singleNumber(int[] A) {
if (A == null || A.length == 0) {
return -1;
}
if (A.length < 3) {
return A[0];
}
Arrays.sort(A);
for (int i = 0; i < A.length; i++) {
if (i + 2 >= A.length - 1 || A[i] != A[i + 2]) {
return A[i];
}
i += 2;
}
return -1;
}
}
思路2:使用三进制异或。存三个变量,ones存出现过一次的数,twos存出现过两次的数,threes则判断这个数是否同时在ones和twos里面出现,若是则说明该数出现了三次,这时需要将这个数从ones和twos中删除。最后的出来的ones就是结果。
Solution2:
public class Solution {
public int singleNumber(int[] A) {
if (A == null || A.length == 0) {
return -1;
}
int ones = 0, twos = 0, threes = 0;
for (int i = 0; i < A.length; i++) {
twos |= ones & A[i];
ones ^= A[i];
threes = ones & twos;
ones &= ~threes;
twos &= ~threes;
}
return ones;
}
}
思路3:模拟三进制异或。即:各个数的某个二进制位之和能被3整除,则说明要寻找的single number在这一位上位0,反之为1。
Solution3:
public int singleNumber(int[] A) {
if (A == null || A.length == 0) {
return -1;
}
int res = 0;
int[] bit = new int[32];
for (int i = 0; i < 32; i++) {
for (int j = 0; j < A.length; j++) {
bit[i] += A[j] >> i & 1;
bit[i] %= 3;
}
res |= bit[i] << i;
}
return res;
}