[Sword refers to offer] Numbers that appear only once in the array

Original blog post, please indicate the source for reprinting!

This topic Niuke network address

Code github address

Index address of other interview questions

 

#title _

image

     

# ideas

      The nature of the XOR operation: the result of XORing any number with itself is 0.

  • An element in the array appears once

      If you XOR each number in the array from beginning to end, the result is a number that occurs only once.

      Example : {4,5,5}, the first element in the array is 0100 in binary form, the second element is 0101 in binary form, and the third element is in binary form 0101. Perform the XOR operation on the three elements in turn, the result of the XOR of 0100 and 0101 is 0001, the result of XOR of 0101 and 0101 is the decimal digit 4 of 0100,0100.

 

  • Two elements in the array appear once

      First split the array into two subarrays, each subarray contains a lone element; then find the lone element from the subarrays separately. The method of array splitting : XOR each number of the array from the beginning to the end, and at least one bit in the binary representation of the result is 1. Set the first bit of 1 in the result as the nth bit, according to whether the nth bit is 1. Divide the numbers in the array into two subarrays, the nth bit of each number in the first subarray is 1, and the nth bit of each number in the second subarray is 0.

      For example : {2, 4, 3, 6, 3, 2, 2, 5}, the result of XORing the elements in the array in turn is 0010, and the first bit of 1 in the result is the third bit. Whether three bits are 1, split the array into two subarrays {2,3,6,3,2} and {4,5,5}.

 

# code

  1  
  2  class Solution {
   3  public :
   4      // data is an array, num1 is the first lonely number, num2 is the second lonely number 
  5      void FindNumsAppearOnce(vector< int > data, int *num1, int *num2)
   6      ​​{
   7          // special input check 
  8          int length = data.size();
   9          if (length < 2)
 10              return ;
 11  
12          // OR of each element of the original array 
13          int resultExclusiveOR = 0;
 14          for ( int i = 0; i < length; ++i)
15              resultExclusiveOR ^= data[i];
 16  
17          // find the first 1 bit in the XOR result 
18          unsigned  int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
 19  
20          // find the numbers num1, num2 
21 that occur only once          *num1 = *num2 = 0;
 22          for ( int j = 0; j < length; j++)
 23              if (IsBit1(data[j], indexOf1))
 24                  *num1 ^= data[j];
 25              else 
26                  *num2 ^= data[j];
 27      }
 28  private :
 29  
30     // Find the first 1 digit of the binary number num, such as 0010, the first 1 digit is 2. 
31      unsigned  int FindFirstBitIs1( int num){
 32          unsigned  int indexBit = 0;
 33          // Only one byte is determined 
34          while ((num & 1) == 0 && (indexBit < 8 * sizeof ( unsigned  int ))){
 35              num = num >> 1;
 36              indexBit++;
 37          }
 38          return indexBit;
 39      }
 40  
41      // Determine if the indexBit is 1 
42      bool IsBit1( intunsigned  int indexBit {
 43 num          = num >> indexBit;
44          return (num & 1);
45      }
 46 };

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324766102&siteId=291194637