Sword refers to the lightness of offer56 questions and the number of numbers in the array of different or deeper understandings (there are 2 different numbers)

Sword refers to the lightness of offer56 questions and the number of numbers in the array of different or deeper understandings (there are 2 different numbers)

Predecessor

It is also about the number of occurrences of the number in the array, but there is only one different number. There are many solutions to this problem, you can create two arrays, or use pointers and other methods to do it, but the time complexity of these methods is not ideal. At this time, it is necessary to play the role of exclusive or. For this bit operator, the first use is when exchanging two numbers (required not to use the third variable, and to ensure that it is within the scope of int). After this method, call the second directly. For this problem, XOR has once again played its magical effect.

#include<stdio.h>
int main()
{
    
    
   int a = 2;
   int b = 3;
   a = a^b;
   b = a^b;
   a = a^b;
   printf("%d%d", a, b);    //此时只需3次异或,就可以交换两个数,而且不用借助第3个变量,同时也可以保证在int的范围内
}  

For the predecessor of this problem, we can also use the XOR operation. XOR all the elements in the array to find the different number, but there is an important premise at this time, that is, those repeated numbers must repeat even numbers Times, because only if it is repeated an even number of times and then XORed with that different number, the result can be that different number.
Here is an inverse

#include<stdio.h>
int main()
{
    
    
	int a[4] = {
    
     1, 1, 1, 4 };
	printf("%d", a[0] ^ a[1] ^ a[2] ^ a[3]);
}

Insert picture description here

At this point, we will find that the result is not what we want, because the repeated number is not repeated even times, but odd times.

At this time, when we look at the Sword Finger offer 56 question, we will find a detail. In the examples it gives, all repeated numbers appear even times. This is not a coincidence, but inevitable.

When you understand the predecessor of this problem, it is not difficult to think whether we can solve this problem with the help of the predecessor's solution, but when we XOR all the elements in the array, we will find that it is not what we want Yes, this is the difficulty of this question. This is where we have to learn analogy. Can we think of a way to separate these two different numbers, and then XOR them, not just turn this problem into Did we have the problem before.

Implementation code

#define RESULT_LEN 2
int* singleNumbers(int* nums, int numsSize, int* returnSize)
{
    
    
       int *ret = (int *)malloc(RESULT_LEN * sizeof(int));
       memset(ret, 0, RESULT_LEN * sizeof(int));
       int s=0;
       int i=0;
       for(i=0;i<numsSize;i++)
       {
    
    
          s^=nums[i];
       }
       int k=1;
       while(k<=s)
       {
    
    
           if((s&k)!=0)
           {
    
    
               break;
           }
           k<<=1;
       }
       for(i=0;i<numsSize;i++)
       {
    
    
           if((nums[i]&k)==0)
           {
    
    
              ret[0]^=nums[i];
           }
       }
       ret[1]=s^ret[0];
       *returnSize=RESULT_LEN;
       return ret; 
}

A brief discussion on each part of the code

     for(i=0;i<numsSize;i++)  
       {
    
    
          s^=nums[i];
       }

XORing all the elements in the array is equivalent to XORing two different numbers, because those same numbers only appear even number of times. This step is mainly to find a distinguishing standard to prepare for the following division, because To separate the two different numbers, there must be a standard to separate them.
2.

     int k=1;        
       while(k<=s)
       {
    
    
           if((s&k)!=0)
           {
    
    
               break;
           }
           k<<=1;
       }

At this time, the result obtained is subjected to an AND operation, the purpose is to find the first digit that is 1, and use this bit as a criterion for distinguishing to divide the array into two. And this can ensure that two different numbers are separated separately. The purpose of finding that the first digit is 1 is to group the numbers whose corresponding digits are 1 into a group, and to group the numbers that are not 1 into a group.
3 .

 for(i=0;i<numsSize;i++)  
       {
    
    
           if((nums[i]&k)==0)
           {
    
    
              ret[0]^=nums[i];
           }
       }

At this time, it has become the predecessor of this problem, and then we can get the number we are looking for by XORing them separately. Here I did not XOR all the numbers with 1 in the corresponding position, because we only need to find a different number. , We can use the property of exclusive-or to find the remaining different number, as long as the number we found is XORed with the result of the initial two-digit XOR once again, the remaining number can be obtained. The code is as follows .

ret[1]=s^ret[0]; 

Regarding exclusive or, there are the following properties.
Commutative law: A ^ B = B ^ A;
associative law: A ^ (B ^ C) = (A ^ B) ^ C;
identity law: X ^ 0 = X;
return to zero Law: X ^ X = 0;
Reflexive: A ^ B ^ B = A ^ 0 = A;
For any X: X ^ (-1) = ~X;
if A ^ B = C holds, then A ^ B = C, B ^ C = A

Summary (actually we met a long time ago)

In fact, the exclusive OR operation, in retrospect, most of us actually had contact in high school. In mathematics, the exclusive OR operation is written as ⊕. It has the following properties

  1. a ⊕ a = 0
  2. a ⊕ b = b ⊕ a
  3. a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c;
  4. d = a ⊕ b ⊕ c, we can deduce a = d ⊕ b ⊕ c.
  5. a ⊕ b ⊕ a = b.

This symbol⊕We actually had some contact with mathematics in high school. There are always some data problems, that is, definition problems will encounter this symbol. This is also a good proof, in fact, knowledge of high school are laying the groundwork for the university, and some knowledge of the university will emerge in high school in the subject, perhaps this is a question of those who place it strong.
By For this question, I also have a deeper understanding of XOR. At the beginning, my understanding of it rested on its use. The same bit is 0, and the different bit is 1. Later, when I exchange two numbers, I have some insights about it. In fact, XOR is the addition and subtraction in the binary system. Now I have a deeper understanding of it.
I understand its many properties. It can be used as a standard for distinguishing. I believe that as I learn more deeply, I will have a deeper understanding of XOR. So far, that is, I have some superficial understanding of Jianzhi offer 56 and some lightness of XOR.

Guess you like

Origin blog.csdn.net/IamGreeHand/article/details/115280663