single number i
题目:有一个数据只出现一次,其他数据都出现两次
思路:位运算(亦或)
class Solution {
public:
int singleNumber(vector<int>& nums) {
for(int i = 1; i < nums.size(); i++)
nums[0] = nums[0] ^ nums[i];
return nums[0];
}
};
single number ii
题目:有一个数据只出现一次,其他数据均出现3次
-
思路:位运算
-
写成2进制数后,对每一位求和(其实是统计每一位出现1的次数),因而可见由重复数据求得的每一位和应该都是3的倍数,因而求余即可知道只出现1次的数据。
class Solution: def singleNumber(self, nums): re = [0]*32 for num in nums: for i in range(32): re[i] += (num >> i) & 1 result = 0 for i in range(32): result += (re[i] % 3) * pow(2, i) return result
现在的复杂度是32*O(N),仍然是线性时间,常数空间。
-
有更简单的方法,更复杂的位运算,不过我表示虽然复杂度更低,然而我理解无能,先贴在这里吧。
class Solution: def singleNumber(self, A): ones,twos=0,0 for ele in A: ones = ones^ele & ~twos twos = twos^ele & ~ones return ones
-
single number iii
题目:只有两个数据出现一次,其他都出现两次
-
思路:当然是位运算
如果只有一个数据只出现一次的话,很简单的求亦或。
两个的话自然有不同。但是我们可以知道的是,若a,b为所求,则前面累计的亦或值re = a^b,而re中为1的数位即是a和b中一个为1一个为0的。
我们随机取一位,那么所有数据可以分成两组。一组该位为1,另一组为0,而a和b分别在这两组中。同样地,我们可以看到,除了a和b之外,每组其他的数据都出现2次。这样我们就转化成了上述的简单求亦或。
-
因而问题变成,取得re中某为1的数位,将数据分成两组。
class Solution(object): def singleNumber(self, nums): re = 0 for num in nums: re ^= num n = re & (~(re - 1))#取为1的最低位 a = 0 b = 0 for num in nums: if n & num:#将数据按该为是否为1分成两组 a ^= num else: b ^= num return a, b
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。