Skip to content

Commit 463e9fb

Browse files
authored
add single_number3: find two elements that appear only once (#260)
* add single_number3: find two elements that appear only once * update README.md - add single_number3 * update single number 3
1 parent 6345650 commit 463e9fb

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ For running all tests write down:
6969
- [find_missing_number](bit/find_missing_number.py)
7070
- [power_of_two](bit/power_of_two.py)
7171
- [reverse_bits](bit/reverse_bits.py)
72-
- [single_number2](bit/single_number2.py)
7372
- [single_number](bit/single_number.py)
73+
- [single_number2](bit/single_number2.py)
74+
- [single_number3](bit/single_number3.py)
7475
- [subsets](bit/subsets.py)
7576
- [add_bitwise_operator](bit/add_bitwise_operator.py)
7677
- [bit_operation](bit/bit_operation.py)

bit/single_number3.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""
2+
Given an array of numbers nums,
3+
in which exactly two elements appear only once
4+
and all the other elements appear exactly twice.
5+
Find the two elements that appear only once.
6+
Limitation: Time Complexity: O(N) and Space Complexity O(1)
7+
8+
For example:
9+
10+
Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].
11+
12+
Note:
13+
The order of the result is not important.
14+
So in the above example, [5, 3] is also correct.
15+
16+
17+
Solution:
18+
1. Use XOR to cancel out the pairs and isolate A^B
19+
2. It is guaranteed that at least 1 bit exists in A^B since
20+
A and B are different numbers. ex) 010 ^ 111 = 101
21+
3. Single out one bit R (right most bit in this solution) to use it as a pivot
22+
4. Divide all numbers into two groups.
23+
One group with a bit in the position R
24+
One group without a bit in the position R
25+
5. Use the same strategy we used in step 1 to isolate A and B from each group.
26+
"""
27+
28+
29+
def single_number3(nums):
30+
"""
31+
:type nums: List[int]
32+
:rtype: List[int]
33+
"""
34+
# isolate a^b from pairs using XOR
35+
ab = 0
36+
for n in nums:
37+
ab ^= n
38+
39+
# isolate right most bit from a^b
40+
right_most = ab & (-ab)
41+
42+
# isolate a and b from a^b
43+
a, b = 0, 0
44+
for n in nums:
45+
if n & right_most:
46+
a ^= n
47+
else:
48+
b ^= n
49+
return [a, b]

tests/test_bit.py

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from bit.reverse_bits import reverse_bits
66
from bit.single_number import single_number
77
from bit.single_number2 import single_number2
8+
from bit.single_number3 import single_number3
89
from bit.subsets import subsets
910
from bit.bit_operation import get_bit, set_bit, clear_bit, update_bit
1011
from bit.swap_pair import swap_pair
@@ -121,6 +122,12 @@ def test_single_number2(self):
121122
random.shuffle(nums)
122123
self.assertEqual(single, single_number2(nums))
123124

125+
def test_single_number3(self):
126+
self.assertEqual(sorted([2,5]),
127+
sorted(single_number3([2, 1, 5, 6, 6, 1])))
128+
self.assertEqual(sorted([4,3]),
129+
sorted(single_number3([9, 9, 4, 3])))
130+
124131
def test_subsets(self):
125132

126133
self.assertSetEqual(subsets([1, 2, 3]),

0 commit comments

Comments
 (0)