本系列一共有三个题目,第一题最为简单,只需要掌握异或运算满足交换律即可。
第二题需要构造一个32位数组,根据二进制的原理,每当某一位上1的数量满足3的倍数时就清零,直到最后找出只出现一次的数字转化为二进制数后各个位置上的1,然后转化成十进制即可。
public class Solution {
public static int singleNumber(int[] A) {
int[] a = new int[32];
int result = 0;
for(int i=0;i<32;i++){
for(int j=0;j<A.length;j++){
if(((A[j]>>i)&1)!=0){
a[i] = (a[i]+1)%3;
}
}
result|= a[i]<<i;
}
return result;
}
}
第三题见到其他数字均出现两次,仍想到使用异或运算,这样一趟下来得到的是两个出现一次数的异或结果,找到其中第一个不为零的位置,则这两个数中的一个在该位置上面为1。然后找到所有在该位上为1的所有数字进行异或,所得必为两个数字之一,这样可的结果。
public class Solution {
public int[] singleNumber(int[] nums) {
int[] result = new int[2];
int temp = 0;
for(int i=0;i<nums.length;i++){
temp ^= nums[i];
}
int count = 0;
int temp1 = temp;
while((temp&1)==0){
count++;
temp>>=1;
}
int temp2 = 0;
for(int i=0;i<nums.length;i++){
if(((nums[i]>>count)&1)!=0)temp2 ^= nums[i];
}
最后,所有位运算要使用左移右移,而不要使用乘除法,原因不明。(temp>>n)&1表示判断第n+1位是否为零。