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
- 0 ^ n = n: 0 XOR any number equals itself
- N ^ N = 0: the number XOR itself is equal to 0
- a ^ b = b ^ a
- ( a ^ b ) ^ c = a ^ ( b ^ c )
- 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
- a = a ^ b; Because it is an assignment operation to a, at this moment a = A ^ B; b = B
- 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;
- 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; } }