[Number of occurrences of numbers in the array - finite state automata]

number of occurrences of a number in an array

Presumably, it is not uncommon for everyone to ask the number of numbers in the array.
There are three main types:
1. Find the number that appears only once in the array (other numbers appear twice)
2. Find the only two numbers in the array Numbers that appear only once (other numbers appear twice)
3. Find the number that appears only once in the array (all other numbers appear three times)

This time I mainly explain the third question, because the first two ideas are easy to come up with and easy to understand.
I put the links of the three questions below:
link: 1, only one number appears once
insert image description here

Links: 2, only two numbers appear once
insert image description here

Links: 3, only one number appears once, and the rest appear three times
insert image description here

1. Finite state automata solution

The general idea:
count the number of occurrences of each 1 among the 32 bits, and take the remainder of 3, and the final result is a number that appears only once. Since the bit operation rules of binary bits are the same, consider one bit
insert image description here
as Can.
As shown in the figure below, the number of a certain binary 1 has only three states: 0, 1, 2
1. If a binary bit 1 is input, the conversion is performed as follows.
2. If the binary digit 0 is input, no conversion is performed.
insert image description here
Since each bit is either 0 or 1, 2 cannot be recorded, so the second status bit is derived and
named respectively: one two means two status bits.
insert image description here

  • The following explains how to update the two status bits of one and two
  • Update of status bit one:
if(two==0)
{
    
    
	if(n==1)
		one=~one;
	else
		one=one;
}
else if(two==1)
{
    
    
	one=0;
}

Yes, simplify it with bitwise operators:
insert image description here

  • Update of the status bit two:
    The update of the status two is carried out according to the updated one (note that it is the updated one)
if(two==1)
{
    
    
	if(n==1)
		{
    
    
			if(one==0)
				two=0;
		}
}
else if(two==0)
{
    
    
	if(n==1)
	{
    
    
		if(one==0)
			two=1;
	}
}

For the convenience of understanding, the above relational expressions can be understood according to the data in the table.
insert image description here
insert image description here

  • code:
  • Note: & has higher precedence than ^
int singleNumber(int* nums, int numsSize){
    
    
    int twos=0,ones=0;
    for(int i=0;i<numsSize;i++)
    {
    
    
        ones = ones ^ nums[i] & ~twos;
        twos = twos ^ nums[i] & ~ones;
    }
    return ones;
}

Although the code is only a few short lines, the amount of thinking involved is not small.

  • Explain why the simplification is necessary:
    ​​because if it is written according to the above if else statement, it is only for a certain bit, and the simplification is for the entire data (that is, 32 bits).

Second, the general solution

The so-called general solution is to record each bit of each data separately, and then perform %3 processing on the number of each bit.

int singleNumber(int* nums, int numsSize){
    
    
    int a[32]={
    
    0};
    for(int i=0;i<numsSize;i++)
    {
    
    
    	for(int j=0;j<32;j++)
    	{
    
    
    		a[j]+=nums[i]&1;
    		nums[i]>>=1;
    	}
    }
    int sum=0;
    for(int i=0;i<32;i++)
    {
    
    
    	sum+=a[i]%3==0?0:(int)pow(2,i);
    }
    return sum;
}

Compared with this solution, it is easier to understand and has strong applicability. No matter how many times other data in the question appears, we only need this one code. But the efficiency is not as good as the above solution.

Guess you like

Origin blog.csdn.net/Djsnxbjans/article/details/128434677