【LeetCode】 338. Nombre de bits

1. Titre

Etant donné un entier non négatif num . Pour chaque chiffre i compris entre 0 ≤ i ≤ num , comptez le nombre de 1 dans son nombre binaire et renvoyez-les sous forme de tableau.

Exemple 1:

输入: 2
输出: [0,1,1]

Exemple 2:

输入: 5
输出: [0,1,1,2,1,2]

Avancée:

  • Il est très facile de donner une solution avec une complexité temporelle de O (n * sizeof (integer)) . Mais pouvez-vous le faire avec un balayage en temps linéaire O (n)?
  • La complexité spatiale de l'algorithme requis est O (n) .
  • Pouvez-vous affiner davantage la solution? Il est nécessaire qu'aucune fonction intégrée (telle que __builtin_popcount en C ++) ne soit utilisée en C ++ ou dans tout autre langage pour effectuer cette opération.

Deux, résolvez

1. Violence

Idées:

Effectuer un calcul de bit sur n'importe quel nombre x (0 <= x <= num). Appelez la fonction de bibliothèque directement ici, bien sûr, vous pouvez également écrire par vous-même.

Code:

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;
    }
}

Complexité temporelle: O (n) O (n)O ( n ) , bitCount () peut être obtenu par 5 opérations, le code source peut être vu:191. Le nombre de
complexité spatiale bit 1:O (n) O (n)O ( n )

2. Changement général

Idées:

Pour tout nombre i, sa représentation binaire est le nombre cnt de 1, et il existe une telle relation: cnt (i) = cnt (i / 2) + i% 2.

Sous une simple compréhension:

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 )==cnt(y)+c n t ( z ) .

z = x% 2 z = x \% 2avec=x % 2zzPourquoi z est-il égal à cette valeur? Maintenant, mettez y en binaire, puisxxxyyy est décalé vers la gauche dans son ensemble, puiszz à la finz , deux possibilités, à savoir 0 ou 1, utilisezxx% 2x signifie que. Ensuite, listez les nombres, les représentations binaires et le nombre de 1 ci-dessous pour vérification et compréhension.

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

Code: Version 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;
    }
}

Code: Version 2, remplacée par un fonctionnement sur bit, qui peut être plus rapide en fonctionnement.

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;
    }
}

Complexité temporelle: O (n) O (n)
Complexité spatiale O ( n ) :O (n) O (n)O ( n )

3. Opération de bit

Idées:

因为 :i & (i - 1) i \ & (i-1)je & ( je-1 ) Rôle: clairiiLe dernier 1 de i .
Donc:iii 1 的 个数 ==i & (i - 1) i \ & (i-1)je & ( je-1 ) Nombre de 1 + 1

Code:

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;
    }
}

Complexité temporelle: O (n) O (n)
Complexité spatiale O ( n ) :O (n) O (n)O ( n )

4. Planification dynamique

Idées:

analyser comme ci-dessous:

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;

Hé, la loi est en fait difficile à résumer, car la variable indépendante offset à l'intérieur est également en train de changer. Étudions-la pour un indice plus tard.

Code:

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;
}

Complexité temporelle: O (n) O (n)
Complexité spatiale O ( n ) :O (n) O (n)O ( n )

Trois, référence

1. Solution Java à trois lignes
2. Comment nous traitons cette question lors de l'entrevue [Processus de réflexion + solution DP]
3. Compréhension facile DP & Bit Solution Java
4, récursivité Java O (n) temps O (1) espace supplémentaire 4ms
5. Comptage de bits
6, connaissance de base des opérations sur les bits

Je suppose que tu aimes

Origine blog.csdn.net/HeavenDan/article/details/108753304
conseillé
Classement