The algorithm enters Dachang from 0 - Part1 - and XOR operation

Posted by pit on Tue, 18 Jan 2022 17:39:56 +0100

XOR and XOR

Recognize XOR

int a = 7;
// At this time, the binary of a is 0111
int b = 13;
// At this time, the binary of b is 1101

So now let's turn a XOR b to 10

0 1 1 1
1 1 0 1
-------
1 0 1 0

Officially, it is the same as 0, but different as 1
 Simply remember that you want to add directly without carrying
 Separate from the same or operation

XOR property

Then we can extend several properties

  1. 0 ^ n = n: 0 XOR any number equals itself
  2. N ^ N = 0: the number XOR itself is equal to 0
  3. a ^ b = b ^ a
  4. ( a ^ b ) ^ c = a ^ ( b ^ c )
  5. The same batch of numbers, no matter what the operation order, the result must be a number

XOR topic

Swap two numbers

//Usually we need intermediate variables to exchange two numbers before
int a = 1;
int b = 2;
int c = 0;
c = a; // 1
a = b; // 2
b = c; // 1

After we learn XOR, we only need three lines of code to change two numbers, and we don't need a third variable

// To facilitate memory and understanding
 a = A;
 b = B;
a = a ^ b;
b = a ^ b;
a = a ^ b;

Now let's analyze the process

  1. a = a ^ b; Because it is an assignment operation to a, at this moment a = A ^ B; b = B
  2. b = a ^ b; The assignment operation to B, so a remains unchanged; a = A ^ B; b = A ^ B ^ B; In the XOR property, we know that B^B=0, so now b = A ^ 0, a number XOR 0 is equal to itself, so B = a;
  3. a = a ^ b = A ^ B ^ A = B. at this time, we have completed the algorithm of exchanging AB

An odd number of occurrences in an array

Problem solving ideas:

​ Prepare a variable called eor = 0, make each number in eor ^ array, and then return eor, which is the number that occurs odd times

Problem solving principle:

​ For example, we have an array nums with a value of 1111222233334 (in order to arrange the order in advance). If you take an eor of 0 to XOR them, can even numbers be eliminated? Then in fact, what you leave behind is eor ^ 4. Because eor is 0 by default, the result is eor = 4

Code demonstration:

Sword finger Offer II 070 Sort numbers that appear only once in the array

136. Figures that appear only once

class Solution {
    public int singleNonDuplicate(int[] nums) {
        int eor = 0;
        for(int i=0; i<nums.length; i++){
            eor = eor ^ nums[i];
        }
        return eor;
    }
}

Extract the rightmost 1 of the integer number

Title Description:

a = 01101110010000
ans = 0000000010000

Problem solving ideas:

a & ~a+1

a = 01101110010000

~a = 10010001101111

~a+1 = 10010001110000 +1 is actually to make the rightmost 1 that becomes 0 in the step of ~ a change back

a&~a+1 = 0000000010000

A & ~ A + 1 = = A & - A, the inverse of a number + 1 = the opposite of this number

Two numbers that appear odd times in the array

Sword finger Offer 56 - I. the number of occurrences of numbers in the array

Problem solving ideas:

​ First of all, let's prepare a variable eor. Let's assume that the array is nums: {1,1,2,3,4,4,5,5}. First, let's use each bit in the eor array, then the even number of occurrences can be eliminated. Finally, eor=23, and then we calculate the binary result of eor at the moment

​ 2 : 0 0 1 0

​ 3 : 0 0 1 1

​ res : 0 0 0 1

​ At this time, we take the rightmost 1, because this 1 can separate the two numbers we obtained. Then we have a variable called res. first, we extract the rightmost 1 of the integer number above, judge whether all the numbers in the array are 1 on the rightmost, that is, the first 0, and divide them into two groups. Then we use eor to XOR if there is 1, Naturally, you will get one of the two odd numbers, save it to res, and finally use res XOR eor to get the last remaining number

Code demonstration:

class Solution {
    public int[] singleNumbers(int[] nums) {
        int eor = 0;
        for(int i=0;i < nums.length; i++){
            eor ^= nums[i];
            //Eventually eor will be the result of these two odd times of difference or
            //eor = a^b
        }
        int rightOne = eor & (~eor+1); // eor & (-eor)
        int otherOne = 0; //The other of the two numbers
        for(int i = 0;i < nums.length; i++){
            //The number on our far right is 000000 1000 
            //If the number in the array & the rightmost number is not equal to 0
            //It means that this position must be 1
            if((nums[i] & rightOne) != 0 ){
                //In other words, my otherOne may be 1 ^ 2 ^ 2 ^ 4 ^ 4 (assumed)
                //According to the even number cancellation, only one number will be left, which is one of the results
                otherOne ^= nums[i];
            }
        }
        //At this point eor = a ^ b, we now find a/b
        //res is the remaining one
        int res = eor ^ otherOne;
        int[] ans = {res,otherOne};
        return ans;
    }
}

Number of occurrences in the array K times

In an array, there are k times for one number and m times for other numbers, M > 1 and K < M. find the number of K times

Sword finger Offer 56 - II Number of occurrences of numbers in the array II

In an array nums, except that one number appears only once, all other numbers appear three times. Please find the number that appears only once. In this topic, k is 1 and M is 3

Problem solving ideas:

​ For example, if my num is {5,5,5,4,3,3,3}, then we all know that the binary of 5 is 0101, the binary of 3 is 0011, and the binary of 4 is 0100. That is to say, in the last bit of the array, our number class plus is 6, that is, int [] num = {00000000.... 000436}, that is, 6 / 3 can be divided, It indicates that the last digit of the number appearing k times is not 1, 3 / 3 division, the penultimate digit of k is not 1, and 4 / 3 has a remainder, so k has 1 here

Code demonstration:

class Solution {
    public int singleNumber(int[] arr) {
        int[] t = new int[32];
        for(int num : arr){
            for(int i =0; i <= 31; i++){
                //Nums > > 0 is itself & 1 is actually the same as 00000001
                //When it is not equal to 0, which bit is 1
                // if(((num >> i) & 1) !=0 ){  
                //     //If it is not equal to 0, it means that bit is 1, so I t[] add 1 to this position class
                //     t[i]++;
                // } 
                t[i] += (num >> i) & 1;
            }
        }
        int ans = 0;
        for(int i = 0; i < 32; i++){
          //This 3 can be replaced by M in different topics
            if(t[i] % 3 != 0){
                // 1 < < move position to item i 
                // Then, or in ans, it is + 1 at the position of ans
                /*
                    For example, ans = 00000000;
                    Now my t [0]= 3, that is, my 0 bit is 1
                    1 << 0 Yes 000000001
                    Or ans = 00000001
                    1 << 1 Yes 000000010
                    Or ans = 00000011
                */
                ans |= (1 << i);
            }
        }
        return ans;
    }
}

Hash table implementation:

class Solution {
    public int singleNumber(int[] arr) {
       HashMap<Integer,Integer> map = new HashMap();
       //Traverse the arr
       for(int num : arr){
           //If the map contains this num
           if(map.containsKey(num)){
               //Then the key of num in the map is + 1
            map.put(num,map.get(num)+1);
           }else{
               //Otherwise, if there is no num in the map, add it, and the key of num is 1
               map.put(num,1);
           }
       }
       //Take out all the key s of the map and traverse
      for(int num:map.keySet()){
          //If key = 1 (can also be k, m, n)
          if(map.get(num) == 1){
              return num;
          }
      }
      return -1;
    }
}

Topics: Algorithm data structure