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; } }