1. Título
Dado un número entero no negativo num . Para cada dígito i en el rango de 0 ≤ i ≤ num , cuente el número de 1 en su número binario y devuélvalos como una matriz.
Ejemplo 1:
输入: 2
输出: [0,1,1]
Ejemplo 2:
输入: 5
输出: [0,1,1,2,1,2]
Avanzado:
- Es muy fácil dar una solución con una complejidad temporal de O (n * sizeof (integer)) . Pero, ¿puede hacerlo con un escaneo en tiempo lineal O (n)?
- La complejidad espacial del algoritmo requerido es O (n) .
- ¿Puede refinar aún más la solución? Se requiere que no se utilicen funciones integradas (como __builtin_popcount en C ++) en C ++ o cualquier otro lenguaje para realizar esta operación.
Dos, resolver
1. Violencia
Ideas:
Realice el cálculo de bits en cualquier número x (0 <= x <= num). Llame a la función de biblioteca directamente aquí, por supuesto, también puede escribir usted mismo.
Código:
class Solution {
public int[] countBits(int num) {
int[] cnt = new int[num+1];
for (int i=0; i<=num; i++) {
cnt[i] = Integer.bitCount(i);
}
return cnt;
}
}
Complejidad de tiempo: O (n) O (n)O ( n ) , bitCount () se puede obtener mediante 5 operaciones, el código fuente se puede ver:191. El número de bits 1
complejidad del espacio: O (n) O (n)O ( n )
2. Turno general
Ideas:
Para cualquier número i, su representación binaria es el número cnt de 1, y existe tal relación: cnt (i) = cnt (i / 2) + i% 2.
Bajo simple entendimiento:
Si x = = 2 y + 0 x == 2y + 0X==2 y+0, 则cnt (x) = = cnt (y) cnt (x) == cnt (y)c n t ( x )==c n t ( y );
若x = = 2 y + zx == 2y + zX==2 y+z, 则cnt (x) = = cnt (y) + cnt (z) cnt (x) == cnt (y) + cnt (z)c n t ( x )==c n t ( y )+c n t ( z ) .
Donde z = x% 2 z = x \% 2con=x % 2,zz¿Por qué z es igual a este valor? Ahora pon y en binario, luegoxxx为 y y y se desplaza a la izquierda como un todo, y luego al final eszzz , dos posibilidades, 0 o 1, usexx% 2x significa eso. Luego, enumere los números, las representaciones binarias y el número de 1 a continuación para su verificación y comprensión.
x 二进制 1个数
0 0 0
1 1 1
2 10 1
3 11 2
4 100 1
5 101 2
6 110 2
7 111 3
8 1000 1
9 1001 2
10 1010 2
11 1011 3
12 1100 2
13 1101 3
14 1110 3
15 1111 4
16 10000 1
Código: Versión 1.
class Solution {
public int[] countBits(int num) {
int[] cnt= new int[num+1];
for (int i=0; i<=num; i++) {
cnt[i] = cnt[i/2] + i%2;
}
return cnt;
}
}
Código: Versión 2, reemplazada por operación de bits, que puede ser más rápida en operación.
class Solution {
public int[] countBits(int num) {
int[] cnt= new int[num+1];
for (int i=0; i<=num; i++) {
cnt[i] = cnt[i>>1] + (i&1);
}
return cnt;
}
}
Complejidad de tiempo: O (n) O (n)O ( n )
complejidad espacial: O (n) O (n)O ( n )
3. Operación de bits
Ideas:
因为 :i & (i - 1) i \ & (i-1)yo & ( yo-1 ) Rol: ClaroiiEl último 1 de i .
Entonces:iii 1 的 个数 ==i & (i - 1) i \ & (i-1)yo & ( yo-1 ) Número de 1 + 1
Código:
class Solution {
public int[] countBits(int num) {
int[] cnt= new int[num+1];
for (int i=1; i<=num; i++) {
cnt[i] = cnt[i&(i-1)] + 1;
}
return cnt;
}
}
Complejidad de tiempo: O (n) O (n)O ( n )
complejidad espacial: O (n) O (n)O ( n )
4. Planificación dinámica
Ideas:
analizar de la siguiente manera:
Index : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
num of 1: 0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4
由上得出:
dp[0] = 0;
dp[1] = dp[0] + 1;
dp[2] = dp[0] + 1;
dp[3] = dp[1] +1;
dp[4] = dp[0] + 1;
dp[5] = dp[1] + 1;
dp[6] = dp[2] + 1;
dp[7] = dp[3] + 1;
dp[8] = dp[0] + 1;
dp[1] = dp[1-1] + 1;
dp[2] = dp[2-2] + 1;
dp[3] = dp[3-2] +1;
dp[4] = dp[4-4] + 1;
dp[5] = dp[5-4] + 1;
dp[6] = dp[6-4] + 1;
dp[7] = dp[7-4] + 1;
dp[8] = dp[8-8] + 1;
dp[index] = dp[index - offset] + 1;
Oye, la ley es realmente difícil de resumir, porque el desplazamiento de la variable independiente interna también está cambiando. Estudiémoslo para obtener una pista más adelante.
Código:
public int[] countBits(int num) {
int result[] = new int[num + 1];
int offset = 1;
for (int index = 1; index < num + 1; ++index){
if (offset * 2 == index){
offset *= 2;
}
result[index] = result[index - offset] + 1;
}
return result;
}
Complejidad de tiempo: O (n) O (n)O ( n )
complejidad espacial: O (n) O (n)O ( n )
Tres, referencia
1. Solución Java de tres líneas
2. Cómo manejamos esta pregunta en la entrevista [Proceso de pensamiento + solución DP]
3. Fácil comprensión de DP y Bit Solución Java
4, recursividad Java O (n) tiempo O (1) espacio extra 4ms
5. Conteo de bits
6, conocimientos básicos de operaciones con bits