【LeetCode】 338. Bitanzahl

1. Titel

Bei einer nicht negativen Ganzzahl num . Zählen Sie für jede Ziffer i im Bereich von 0 ≤ i ≤ num die Anzahl der Einsen in ihrer Binärzahl und geben Sie sie als Array zurück.

Beispiel 1:

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

Beispiel 2:

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

Fortgeschrittene:

  • Es ist sehr einfach , eine Lösung mit einer zeitlichen Komplexität von O (n * sizeof (Ganzzahl)) zu geben . Aber können Sie es mit einem Scan in der linearen Zeit O (n) tun?
  • Die räumliche Komplexität des erforderlichen Algorithmus beträgt O (n) .
  • Können Sie die Lösung weiter verfeinern? Es ist erforderlich, dass in C ++ oder einer anderen Sprache keine integrierten Funktionen (wie __builtin_popcount in C ++) verwendet werden , um diesen Vorgang auszuführen.

Zwei, lösen

1. Gewalt

Ideen:

Führen Sie eine Bitberechnung für eine beliebige Zahl x durch (0 <= x <= num). Rufen Sie die Bibliotheksfunktion direkt hier auf, natürlich können Sie auch selbst schreiben.

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

Zeitkomplexität: O (n) O (n)O ( n ) , bitCount () kann durch 5 Operationen erhalten werden, der Quellcode ist zu sehen:191. Die Anzahl der Bits 1
Raumkomplexität: O (n) O (n)O ( n )

2. Gesamtverschiebung

Ideen:

Für jede Zahl i ist ihre binäre Darstellung die Zahl cnt von 1, und es gibt eine solche Beziehung: cnt (i) = cnt (i / 2) + i% 2.

Unter einfachem Verständnis:

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

Wobei z = x% 2 z = x \% 2mit=x % 2zzWarum ist z gleich diesem Wert? Setzen Sie nun y in binär und dannxxxyyy wird als Ganzes nach links verschoben und ist am Endezzz , zwei Möglichkeiten, 0 oder 1, verwendenxx% 2x bedeutet das. Listen Sie dann die Zahlen, binären Darstellungen und die Anzahl der Einsen zur Überprüfung und zum Verständnis auf.

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, ersetzt durch Bitoperation, die möglicherweise schneller arbeitet.

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

Zeitkomplexität: O (n) O (n)O ( n )
Raumkomplexität: O (n) O (n)O ( n )

3. Bitbetrieb

Ideen:

因为 :i & (i - 1) i \ & (i-1)ich & ( ich- -1 ) Rolle: KlariiDie letzte 1 von i .
Also:iii 1 的 个数 ==i & (i - 1) i \ & (i-1)ich & ( ich- -1 ) Anzahl von 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;
    }
}

Zeitkomplexität: O (n) O (n)O ( n )
Raumkomplexität: O (n) O (n)O ( n )

4. Dynamische Planung

Ideen:

analysieren wie folgt:

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;

Hey, das Gesetz ist eigentlich schwer zusammenzufassen, da sich auch der unabhängige Variablenversatz im Inneren ändert. Lassen Sie es uns später untersuchen, um einen Hinweis zu erhalten.

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

Zeitkomplexität: O (n) O (n)O ( n )
Raumkomplexität: O (n) O (n)O ( n )

Drei, Referenz

1. Dreizeilige Java-Lösung
2. Wie wir mit dieser Frage im Interview umgehen [Denkprozess + DP-Lösung]
3. Einfaches Verständnis DP & Bit Java-Lösung
4, Java-Rekursion O (n) Zeit O (1) zusätzlicher Speicherplatz 4 ms
5. Bitzählung
6, Grundkenntnisse über Bitoperationen

Ich denke du magst

Origin blog.csdn.net/HeavenDan/article/details/108753304
Empfohlen
Rangfolge