【剑指Offer】面试题56-2:数组中唯一只出现一次的数字

题目:在一个数组中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

思路 1:排序后遍历

和上一题一样,最直观的思路是:对数组先排序,然后从头到尾遍历,找出只出现一次的数字。但是这种算法的时间复杂度是 $O(n\,log\,n)$。我们需要思考更快的算法。

思路 2:哈希表

另外一种直观的思路是:首先第一次遍历数组,并使用哈希表记录每个数字出现的次数;然后第二次遍历数组,找出次数为 1 的那个数字。这种算法的时间复杂度是 O(n),但是需要一个哈希表,空间复杂度是 O(n)。我们需要降低空间复杂度。

思路 3:位计数

一个数字的二进制表示中有些位为 0,有些位为 1。因此如果这个数字出现 3 次,假如我们使用某个位数组记录每一位的和,那么这个位数组中的每个数都能够整除 3。所以这个思路是:使用一个数组记录每个数字的二进制表示中位的和,把数组中所有的数字按位相加并将结果存到位数组中,然后把位数组中的每个数值整除 3,如果能够整除,说明只出现一次的数字在该位上等于 0,否则等于 1,最终还原数字即可。这个算法的时间复杂度是 O(n);只需要一个容量位 32 的数组,空间复杂度是 O(1)。