Skip to content

Commit 9e4c224

Browse files
committed
leetcode 260
1 parent d6d0c41 commit 9e4c224

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

剑指offer/40_NumbersAppearOnce(数组中只出现一次的数字).py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
class Solution1:
3232
def singleNumber(self, nums):
3333
"""
34+
类似题:求只出现一次的数字,其他都出现两次。
3435
:type nums: List[int]
3536
:rtype: int
3637
"""
@@ -58,12 +59,45 @@ def get_single_num(nums):
5859
while single & mask == 0:
5960
mask = mask << 1
6061

61-
print(mask,'||||||||||||||||||')
62+
print(mask, '||||||||||||||||||')
6263
left = [i for i in nums if i & mask]
6364
right = [i for i in nums if not(i & mask)]
6465
return [get_single_num(left), get_single_num(right)]
6566

6667

68+
class Solution(object):
69+
def singleNumber(self, nums):
70+
"""
71+
思路:异或。
72+
73+
136 题做过只出现一次的一个数字,本题有两个只出现一次的数字。
74+
核心在于把数组分成两个。怎么分组呢?
75+
76+
假设只出现一次的数字式 x1,x2,所有元素异或结果是 x。一定有 x=x1^x2。
77+
x不能是0,否则x1==x2,就不是只出现一次的数字了。
78+
*可以用位运算 x&-x 取出x 二进制位最低位的 1,设其实是第 L 位置。*
79+
可以据此分类数组,一组是二进制第 L位置为 0 的数字,一组L 位置为 1的数字。
80+
x1,x2会分别出现在两个组中。这样第一组全部异或得到x1, 第二组全部异或得到 x2
81+
82+
:type nums: List[int]
83+
:rtype: List[int]
84+
"""
85+
x = 0
86+
for num in nums:
87+
x ^= num
88+
89+
low1pos = x & -x # 这里也可以用移位运算,x&-x 不太好想,类似上边那个解法
90+
x1, x2 = 0, 0
91+
92+
for num in nums:
93+
if num & low1pos:
94+
x1 ^= num
95+
else:
96+
x2 ^= num
97+
98+
return x1, x2
99+
100+
67101
def test():
68102
s = Solution()
69103
assert s.singleNumber([1, 2, 1, 3, 2, 5]) == [3, 5]

0 commit comments

Comments
 (0)