leetcode_137. Number II that only appears once

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
Insert picture description here
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
Insert picture description here
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.
Insert picture description here

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)&1look at the right side of the equation, which e>>imeans 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)<<ito see the right side of the equation cnt%3represents 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.
Insert picture description here

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;
    }
};

Guess you like

Origin blog.csdn.net/qq_44443986/article/details/115279679