leetcode [137]Single Number II

Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

Input: [2,2,3,2]
Output: 3

Example 2:

Input: [0,1,0,1,0,1,99]
Output: 99

题目大意:

给定一个数组,数组中只有一个数出现了一次,其他数字都出现了三次,找出出现一次的数字。

解法:

使用count记录nums中每一位中1出现的次数,如果count%3=1的话,那么目标数在该位置上也是1。然后重新构造出该数字。

java:

class Solution {
    public int singleNumber(int[] nums) {
        int res=0;
        for(int i=0;i<32;i++){
            int count=0;
            for(int num:nums){
                if(((num>>i)&1)==1) count++;
            }
            if(count%3==1) res|=(1<<i);
        }
        return res;
    }
}

优化过后的java:

   如果是出现两次的话,用一个bit就可以

    比如 b,初始为0
    当5第1次出现时, b=5
    当5第2次出现是, b清空为0,表示b可以去处理其他数字了
    所以,最后 如果 b !=0的话,b记录的就是只出现了一次的那个数字
    
    ->公式就是 b = b xor i  或者 b = b^i


    那么,如果是三次的话,香浓定理,需要用2bits进行记录

    当5第一次出现的时候,b = 5, a=0,  b记录这个数字
    当5第二次出现的时候,b = 0, a=5, a记录了这个数字
    当5第三次出现的时候,b = 0, a=0, 都清空了,可以去处理其他数字了
    所以,如果有某个数字出现了1次,就存在b中,出现了两次,就存在a中,所以返回 a|b

    公式方面 ,上面两次的时候,b清空的公式是 b = b xor i
            而第三次时,b要等于零,而这时a是True,所以再 & 一个a的非就可以,b = b xor & ~a
    -> b = b xor i & ~ a
       a = a xor i & ~b
class Solution {
    public int singleNumber(int[] nums) {
        int a=0,b=0;
        for(int i=0;i<nums.length;i++){
            b=(b^nums[i])&~a;
            a=(a^nums[i])&~b;
        }
        return b;
    }
}
posted @ 2019-04-17 21:28  小白兔云  阅读(107)  评论(0编辑  收藏  举报