Description
Given an integer array nums
, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once. You can return the answer in any order.
You must write an algorithm that runs in linear runtime complexity and uses only constant extra space.
Examples:
Example 1:
Input: nums = [1,2,1,3,2,5]
Output: [3,5]
Explanation: [5, 3] is also a valid answer.
Example 2:
Input: nums = [-1,0]
Output: [-1,0]
Example 3:
Input: nums = [0,1]
Output: [1,0]
Solution in Python
Python
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
# Step 1: XOR all the numbers together. The result will be the XOR of the two unique numbers.
xor_result = 0
for num in nums:
xor_result ^= num
# Step 2: Find the rightmost set bit in the xor_result (i.e., where the two unique numbers differ)
# This helps in dividing the numbers into two groups.
rightmost_bit = xor_result & -xor_result
# Step 3: Use the rightmost bit to partition numbers into two groups and XOR them separately
# One group will have one of the unique numbers and the other group will have the other unique number.
num1, num2 = 0, 0
for num in nums:
if num & rightmost_bit:
num1 ^= num
else:
num2 ^= num
# Return the two unique numbers
return [num1, num2]
Explanation:
- Step 1: XOR of All Numbers:
- The key observation is that if you XOR all numbers in the array, the result will be the XOR of the two unique numbers. This is because numbers that appear twice will cancel each other out (since
a ^ a = 0
). - After this step,
xor_result
will be the XOR of the two unique numbers.
- The key observation is that if you XOR all numbers in the array, the result will be the XOR of the two unique numbers. This is because numbers that appear twice will cancel each other out (since
- Step 2: Find Rightmost Set Bit:
- To differentiate the two unique numbers, find the rightmost set bit (bit that is
1
) in thexor_result
. This bit is where the two unique numbers differ. - The expression
xor_result & -xor_result
gives the rightmost set bit. This works because-xor_result
is the two’s complement ofxor_result
, and ANDing the two isolates the lowest set bit.
- To differentiate the two unique numbers, find the rightmost set bit (bit that is
- Step 3: Partition the Numbers:
- Using the rightmost set bit, partition the numbers into two groups:
- One group where this bit is set (i.e.,
num & rightmost_bit != 0
). - The other group where this bit is not set.
- One group where this bit is set (i.e.,
- XOR all numbers in each group separately. Since all numbers except the unique ones appear twice, XORing within each group will leave us with one unique number in each group.
- Using the rightmost set bit, partition the numbers into two groups:
- Return the Result:
- The two XOR results from the two groups are the two unique numbers. Return them as a list.
Solution in C++
C++
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
unordered_map<int, int> countMap;
// Step 1: Count occurrences of each number
for (int num : nums) {
countMap[num]++;
}
// Step 2: Find the two numbers that appear only once
vector<int> result;
for (const auto& entry : countMap) {
if (entry.second == 1) {
result.push_back(entry.first);
}
}
return result;
}
};
Solution in Javascript
JavaScript
var singleNumber = function(nums) {
// Step 1: Initialize xorSum to 0
let xorSum = 0;
// Step 2: XOR all numbers in the array
for (let num of nums) {
xorSum ^= num; // This will result in the XOR of the two unique numbers
}
// Step 3: Find the rightmost set bit in xorSum
// We use the expression xorSum & (-xorSum) to isolate the rightmost set bit
const diffBit = xorSum & -xorSum;
// Step 4: Initialize variables for the two unique numbers
let x = 0, y = 0;
// Step 5: Divide numbers into two groups based on the diffBit and XOR within the groups
for (let num of nums) {
if (num & diffBit) {
x ^= num; // XOR numbers where the diffBit is set
} else {
y ^= num; // XOR numbers where the diffBit is not set
}
}
// Step 6: Return the two unique numbers in an array
return [x, y];
};
Solution in Java
Java
class Solution {
public int[] singleNumber(int[] nums) {
// Step 1: Initialize xorSum to 0
int xorSum = 0;
// Step 2: XOR all numbers in the array
for (int num : nums) {
xorSum ^= num; // This will result in the XOR of the two unique numbers
}
// Step 3: Find the rightmost set bit in xorSum
// We use the expression xorSum & -xorSum to isolate the rightmost set bit
int diffBit = xorSum & -xorSum;
// Step 4: Initialize variables for the two unique numbers
int x = 0, y = 0;
// Step 5: Divide numbers into two groups based on the diffBit and XOR within the groups
for (int num : nums) {
if ((num & diffBit) != 0) {
x ^= num; // XOR numbers where the diffBit is set
} else {
y ^= num; // XOR numbers where the diffBit is not set
}
}
// Step 6: Return the two unique numbers in an array
return new int[] { x, y };
}
}