《剑指offer》面试题56(2):

题目:数组中唯一只出现一次的数字

在一个整数数组中除了一个数字只出现一次外,其他数字都出现三次。找出那个出现一次的数字。


思路:

如果题目中的“三次”换成“两次”,这道题目将非常简单,因此两个相同的数字异或,每一位都会变成0,其实亦或也可以看成两个数字的每一个二进制位对应进行加法后对2取模后的结果。按照这种思路,对于出现三次的数字,改成对3取模即可。举个例子说明下(10,4,5,5,4,4,5):

相关数字对应二进制表示:10 = 1010      4 = 0100     5 = 0101
1)申请一个长度为32(因为int占32bit)的int型数组bitsum,用于记录整型数字每一位出现1的次数。
bitsum = 00000000 00000000 00000000 00000000

2)将每个数字计入到bitsum[]中
10-> 00000000 00000000 00000000 00001010
4 -> 00000000 00000000 00000000 00001110
5 -> 00000000 00000000 00000000 00001211
5 -> 00000000 00000000 00000000 00001312
4 -> 00000000 00000000 00000000 00001412
4 -> 00000000 00000000 00000000 00001512
5 -> 00000000 00000000 00000000 00001613

3)bitsum的每一个元素对3取模:
bitsum = 00000000 00000000 00000000 00001010

4)将bitsum作为一个32bit的整数:
result = 00000000 00000000 00000000 00001010 = 10

基于以上分析,java参考代码如下:

public class NumberAppearOnce {
    public static int findNumberAppearOnce(int[] data){
        if(data==null ||data.length<3)
            return 0; //为了方便返回0,但其实并不能区分异常
            
        // 存储一个int(长度32bit)的每个bit的状态
        int[] bitSum = new int[32];
        int k = 3;
        for(int i=0;i<data.length;i++){
            int indexOfBit1 = 1;
            for(int j=31;j>=0;j--){//从31~0
                if((data[i]&indexOfBit1)!=0)
                    bitSum[j] += 1;
                indexOfBit1<<=1;
            }
        }
        int result = 0;
        for(int i=0;i<32;i++){//从0~31
            result<<=1; //先移位
            result+=bitSum[i]%k; //result所加的数字只会是0或者1
        }
        return result;
    }
  
    public static void main(String[] args){
        int[] data1 = new int[]{10,4,5,3,5,4,3,3,4,5};//10
        int[] data2 = new int[]{0,-4,5,3,5,-4,3,3,-4,5};//0
        int[] data3 = new int[]{-10,-4,5,3,5,-4,3,3,-4,5};//-10
        
        System.out.println(findNumberAppearOnce(data1));
        System.out.println(findNumberAppearOnce(data2));
        System.out.println(findNumberAppearOnce(data3));
    }
}

测试用例:

a.功能测试(唯一只出现一次的数字分别是0、正数、负数;重复出现三次的数字分别是0、正数、负数)。

参考:

https://www.jianshu.com/p/258785bdf416

猜你喜欢

转载自blog.csdn.net/qq_43502142/article/details/87628454