Potencia de Dos
Este problema consiste en, dado un entero n, regresar verdadero si es una potencia de dos y falso en caso contrario. Un entero es potencia de dos si existe un entero x tal que n == 2^x.
Solución
Mi primera solución genera las potencias de dos una por una y las compara con n:
class Solution {
public:
bool isPowerOfTwo(int n) {
if (n <= 0)
return false;
int j = 1;
for (int i{0}; i < 31; i++) {
if (j == n)
return true;
j = j << 1;
}
return false;
}
};
Se descartan los valores no positivos. Después se parte de 1 y se va desplazando a la izquierda (multiplicando por 2) hasta 31 veces, comparando en cada paso con n. Como un entero de 32 bits con signo solo puede representar potencias de dos hasta 2^30, 31 iteraciones son suficientes.
Una mejor solución usa una propiedad de los bits: una potencia de dos tiene exactamente un bit encendido, por lo que al restarle 1 se invierten su bit y todos los ceros a su derecha; si se aplica un AND entre n y n - 1 el resultado es 0.
class Solution {
public:
bool isPowerOfTwo(int n) {
return n > 0 && (n & (n - 1)) == 0;
}
};
La condición n > 0 descarta el 0 y los negativos, y (n & (n - 1)) == 0 verifica que solo haya un bit encendido. Se resuelve en tiempo constante.