Given an 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?
此题不是很好理解,首先,之前的single number是解决不了这个问题的,因为这个里面全是奇数次,而奇数次之后的结果就是都是它们本身,不过此题还是用位操作来做的,想法如下:
首先,因为次数最多是3次,所以用两个位来做,假设a为第一个bit,b为第二个bit,我们就有:
a = a^r&~b;
b = b^r&~a;
00+1=01;
01+1=10;
10+1=00;
此题可以解决次数为奇数次的情况,代码如下:
1 public class Solution { 2 public int singleNumber(int[] nums) { 3 int a=0; 4 int b=0; 5 for(int i=0;i<nums.length;i++){ 6 a = a^nums[i]&(~b); 7 b = b^nums[i]&(~a); 8 } 9 return a; 10 11 } 12 }
这个解法对于解决五次的问题还是不是很好理解的,先上代码:
1 int singleNumber(int A[], int n) { 2 int twos = 0xffffffff, threes = 0xffffffff, ones = 0; 3 for(int i = 0; i < n; i++){ 4 threes = threes ^ (A[i] & twos); 5 twos = (twos ^ A[i]) & ~ones; 6 ones = ones ^ (A[i] & ~twos & ~threes); 7 } 8 return ones; 9 }
看了别人的做法,发现了可以用求余的做法来做,代码如下:
1 public class Solution { 2 public int singleNumber(int[] nums) { 3 int ans = 0; 4 for(int i=0;i<32;i++){ 5 int sum = 0; 6 for(int j=0;j<nums.length;j++){ 7 if(((nums[j]>>i)&1)==1){ 8 sum++; 9 sum%=3; 10 } 11 } 12 if(sum>0){ 13 ans = ans|(sum<<i); 14 } 15 } 16 return ans; 17 } 18 }