[Notas del algoritmo] Las maravillas de la operación XOR

Prefacio: Este capítulo resume principalmente varios pequeños temas relacionados con las operaciones XOR. Si los domina, ¡puede tener sorpresas inesperadas al escribir algunos problemas de algoritmos!

1. Introducción básica

  • El XOR de dos números idénticos cualesquiera es 0
  • Un número y 0 XOR el resultado sin cambios
  • El XOR de números múltiples sigue la ley conmutativa
  • Esto se puede hacer ans |= (1 << i)configurando la posición i del binario ans en 1

2. Temas

Pregunta 1: Cómo intercambiar dos números a y b sin variables adicionales

Plantilla de método:

a = a ^ b;
b = a ^ b;
a = a ^ b;

Código de muestra:

int a = 3;
int b = 5;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a + " " + b);
// 结果为:5 3

Darse cuenta:

XOR también se puede usar para intercambiar dos valores en una matriz, pero debe tenerse en cuenta que los dos subíndices de la matriz no pueden ser iguales, de lo contrario, el valor intercambiado será incorrecto

Pregunta 2: en una matriz, un número aparece veces impares y otros números aparecen veces pares, cómo encontrar e imprimir este número

Plantilla de método: XOR todos los números juntos, el resultado XOR del valor par es 0, el resultado del valor impar es el valor en sí, y el resultado XOR de cualquier valor y 0 permanece sin cambios.

public static void printOddTimesNum1(int[] arr) {
    
    
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
    
    
        eor ^= arr[i];
    }
    System.out.println(eor);
}

Código de muestra:

public static void main(String args[]) {
    
    
    int[] arr = {
    
    1, 1, 2, 3, 3, 4, 4};
    printOddTimesNum1(arr);
}
// 结果为:2

Pregunta 3: Cómo extraer un número a de tipo int, solo mantener la posición más a la derecha de 1 en el binario, y el valor del resto de los bits se modifica a 0 (como 1110 -> 0010)

Plantilla de método:

a = a & (~a + 1)
    
a = a & (-a)

Código de muestra:

int num = 10;	// 10 的二进制为 1010
int num1 = num & (~num + 1);
int num2 = num & (-num);
System.out.println(num1);
System.out.println(num2);
// 结果都为:2	(2 的二进制为 0010)

Pregunta 4: Hay dos tipos de números a y b en una matriz que aparecen un número impar de veces, y otros números aparecen un número par de veces, cómo encontrar e imprimir estos dos tipos de números

Plantilla de método: XOR todos los números en la matriz, y el resultado es a ^ b, ya que a y b no son iguales, el resultado XOR definitivamente no es 0, es decir, el valor binario del resultado debe tener un bit de 1, por lo que el El resultado puede ser La posición donde una determinada posición del binario es 1 se usa como límite. Debe haber algunos números en la matriz cuyo valor sea 1. Por lo tanto, puede encontrar todos los números cuya posición es 1 y realizar XOR en Supongamos que el resultado XOR es a, entonces a a ^ bse para obtener b

public static void printOddTimesNum2(int[] arr) {
    
    
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
    
    
        eor ^= arr[i];
    }
    int rightOne = eor & (-eor); // 提取出最右的1
    int a = 0;
    for (int i = 0 ; i < arr.length;i++) {
    
    
        if ((arr[i] & rightOne) != 0) {
    
    
            a ^= arr[i];
        }
    }
    int b = eor ^ a; 
    System.out.println(a + " " + b);
}

Código de muestra:

public static void main(String args[]) {
    
    
    int[] arr = {
    
    1, 1, 2, 3, 3, 4, 4, 5};
    printOddTimesNum2(arr);
}
// 结果为:5 2

Pregunta 5: En una matriz, un número aparece K veces y otros números aparecen M veces (M > 1, K < M). Para encontrar el número que aparece K veces, la complejidad espacial adicional es O(1), El tiempo la complejidad es O(N)

Método de plantilla: puede solicitar una matriz con una longitud de matriz de 32, que en realidad representa el binario de 32 bits de una matriz, que se utiliza para calcular el número total de 1 en cada posición del binario para todos los números en el matriz original. El valor de cada bit del arreglo aplicado es módulo M. Si el resultado es 0, significa que el valor del bit del número de ocurrencias es 0, si el resultado no es 0, significa que el número de ocurrencias es K. El valor de este bit es 1. Tenga en cuenta que cuando el número de ocurrencias es K y el valor es 0, las condiciones anteriores no se cumplen y se requiere un procesamiento especial.

public static int onlyKTimes(int[] arr, int K, int M) {
    
    
    int[] bin = new int[32];
    for(int num : arr) {
    
    
        for(int i = 0; i < 32; i++) {
    
    
            bin[i] += (num >> i) & 1;
        }
    }
    int ans = 0;
    for(int i = 0; i < 32; i++) {
    
    
        if(bin[i] % M == 0) {
    
    
            continue;
        }
        // 模的值必须为 K 才满足条件,如果不满足就返回一个 -1
        if(bin[i] % M == K) {
    
    
            // 将 ans 的 i 位置设置为1
            ans |= (1 << i);
        }else {
    
    
            return -1;
        }
    }
    return ans;
}

Código de muestra:

public static void main(String args[]) {
    
    
    int[] arr = {
    
    1, 1, 1, 9, 9, 3, 3, 3, 4, 4, 4};
    System.out.println(onlyKTimes(arr,2,3));
}
// 结果为:9

Supongo que te gusta

Origin blog.csdn.net/weixin_51367845/article/details/123159061
Recomendado
Clasificación