bit-operation
Reference - Acm之家
Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
原题链接:http://oj.leetcode.com/problems/single-number-ii/
问题:给一个数组,里面只有一个数字一次,其它数字都出现3次,找出这个出现一次的数字,要求时间复杂度为O(n),空间复杂度为O(1)。
例子:
Input: arr[] = {12, 1, 12, 3, 12, 1, 1, 2, 3, 3}
Output: 2
方法1: 可以通过排序在O(nlogn)的时间内解决,也可以用hash,但是最坏的情况下复杂度可能会超过O(n),hash需要的空间复杂度也比较大。
方法2: 前面的Single Number[位运算] 是一个很简单的位运算题目。
这里的思想是还是位运算的方法解决。并不是简单的异或等操作,因为所有的数字都是出现奇数次。大家可以先参考careercup上面的这个面试题。
方法3: 这里我们需要重新思考,计算机是怎么存储数字的。考虑全部用二进制表示,如果我们把 第ith个位置上所有数字的和对3(3指的是出现的次数)取余,那么只会有两个结果 0 或 1 (根据题意,3个0或3个1相加余数都为0). 因此取余的结果就是那个 “Single Number”. 一个直接的实现就是用大小为 32的数组来记录所有 位上的和。
code
class Solution {
public:
int singleNumber(int A[], int n) {
if(n == 1) return A[0];
int result = 0;
// 2^32
const int bitNum = 32;
int bitArr[bitNum] = {0};
for(int i = 0; i < n; i++) {
int j = 0;
while(j < bitNum) {
// determine odd or even
if ((A[i] >> j) & 1) {
bitArr[j]++;
}
j++;
}
}
const int num = 3;
const int base = 1;
for(int i = 0; i < bitNum; i++) {
// mod the times
bitArr[i] = bitArr[i] % num;
// get target
result += (base << i) * bitArr[i];
}
return result;
}
};