137. 只出现一次的数字 II

题目

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,3,2]
输出: 3

示例 2:

输入: [0,1,0,1,0,1,99]
输出: 99

思路

计算二进制下,各个位上1的个数。

因为只有一个数出现1次,其他都出现3次,所以各个位上1的个数%3就是只出现1次的数的二进制表示。

  比如[2,2,4,2],二进制就是[0010,0010,0100,0010],那么二进制对应位上1的个数位0 1 3 0,然后%3位0 1 0 0。也就是只出现1次的4。

因为%3那么1的个数可能为0,1,2。用2位二进制表示即可。

  比如a=0010,b=0001(a高位,b低位)表示各个位上1的个数:0 0 2 1 [00 00 10 01]。

假设下一个数为c,可以知道:1、c的二进制位上为1时,b对应位肯定会发生变化。2、只有b对应位上由1变为0时,a对应位才会发生变化。3、当某个位上1的个数为3时,即a、b对应位都为1,置为0.

那么1、只要c对应位是1,b对应位就变化:t=b^c;2、b对应位由1变为0时,a变化:a=c&b^a;(b更新:b=t;)3、当a、b对应位都为1时,置为0:temp=a;a=a^a&b;b=b^temp&b;(&优先级>^)

因为最后的结果表示的是一个数的二进制,那么对应位的1的个数只可能是1或0,那么低位的b就是最终的结果。

代码

public static int singleNumber(int[] nums) {
        int a=0;
        int b=0;
        for(int i=0;i<nums.length;++i){
            int t=b^nums[i];
            a=nums[i]&b^a;
            b=t;
            int c=a;
            a=a^a&b;
            b=b^c&b;
        }
        return b;
    }

 

 



posted @ 2018-08-31 21:55  喝醉的香锅锅  阅读(690)  评论(0编辑  收藏  举报