https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b34ad804-b5b6-4399-91e1-1da026e7fa89/Untitled.png

Important properties of XOR to remember

Following are some important properties of XOR to remember:

Use cases

Single Number

If we xor number to itself we get zero. So we end up with single number.

public int findSingleNumber(int[] arr) {
    int xor = arr[0];
    for (int i = 1; i < arr.length; i++) {
        xor ^= arr[i];
    }
    return xor;
}

Two Single Numbers

Tricky case. We assume that n1 and n2 have one bit difference between them.

So we do xor and find xored number. Taking rightmostSetBit.

Then we can partition numbers if the bit is set or not and find both.

public static int[] findSingleNumbers(int[] nums) {
    // get the XOR of the all the numbers
    int n1xn2 = 0;
    for (int num : nums) {
      n1xn2 ^= num;
    }

    // get the rightmost bit that is '1'
    int rightmostSetBit = 1;
    while ((rightmostSetBit & n1xn2) == 0) {
      rightmostSetBit = rightmostSetBit << 1;
    }
    int num1 = 0, num2 = 0;
    for (int num : nums) {
      if ((num & rightmostSetBit) != 0) // the bit is set
        num1 ^= num;
      else // the bit is not set
        num2 ^= num;
    }
    return new int[] { num1, num2 };
  }

Complement of Base 10 Number

XOR of a number with its complement will result in a number that has all of its bits set to 1!

We calculate bitCount by moving bit right n >> 1.

All bits set value is 2^N - 1, cause 2^N wil give us smth like 10000.... and - 1 → 11111

Then just do XOR to all bits set.