table of Contents
1. Subject content
Given an array of non-empty integers, except for an element that appears only once, each of the other elements appears three times. Find the element that appears only once.
Explanation:
Your algorithm should have linear time complexity. Can you do it without using extra space?
Example 1:
Input: [2,2,3,2]
Output: 3
Example 2:
Input: [0,1,0,1,0,1,99]
Output: 99
leetcode_137. Number II that only appears once
Two, problem solving ideas
Prerequisite knowledge: This question is used in the |
, &
, >>
, <<
operation, first to explain their meaning
|
: 1 to 1, not a 0, for example, 1101 | 1000 = 1101
&
: 1 is 1 are, for example, 1101 & 1000 = 1000
>>
shift right, for example 2 >> 1 = 0010 >> 1 = 0100 = 4
<<
shift left, for example 2 << 1 = 0010 << 1 = 0001 = 1
Logic principle: We treat all numbers as binary digits. First, we don’t consider the number that appears alone. Let’s use [2,2,3,2] as an example. 2 is replaced by binary system, which is 0010. Addition
If the corresponding binary number is 1, then the number of times they appear must be a multiple of 3. At this time, add the number that appears separately and consider that
we find a rule. If each corresponding binary is modulo Above 3, the result must be 1 or 0, if the result is 1, then it must be on the binary digit that appears alone. If the number appears 3, 6, or 9 times, the result of the modulo 3 is all 0, which means that the single number has not appeared in the binary digit, that is, it is 0 at the position.
Code implementation principle (look at the code together): Each number has 32 bits, so we loop 32 times and count the number of occurrences of 1 on each bit, and then nest a loop inside to traverse each number. Count the number of occurrences at that position. When traversing, define a counter to record the number of occurrences. First cnt+=(e>>i)&1
look at the right side of the equation, which e>>i
means the result of shifting the number e to the right by i times, and then add it to the previous 1, if the position is 1, then add it to the counter cnt in. After traversal, look res|=(cnt%3)<<i
to see the right side of the equation cnt%3
represents 1 to see whether it is on an individual numbers that at this position, then the i-bit left shift the result, return to the original binary position, look to the right res|=
with the result or The result on the right side of the above equation.
Three, the code
class Solution {
public:
int singleNumber(vector<int>& nums)
{
int res = 0;
for (int i = 0; i < 32; ++i)
{
int cnt = 0;
for (auto& e:nums)
{
//获取每个位上的个数
cnt += (e >> i) & 1;
}
//模3再右移i,表示该数原本应该在的位置,再或上之前的结果
res |= (cnt % 3) << i;
}
return res;
}
};