[LeetCode] 233. Le numéro du numéro 1 (la même épée fait référence à Offer43)

1. Titre

Étant donné un entier n, comptez le nombre d'occurrences du nombre 1 dans tous les entiers non négatifs inférieurs ou égaux à n.

Exemple:

输入: 13
输出: 6 
解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13

Deux, résolvez

1. fissuration par force brute

Idées:

Après avoir lu le sujet, vous pouvez écrire le code directement, mais les temps de la méthode sur .

Code:

class Solution {
    
    
    public int countDigitOne(int n) {
    
    
        int cnt = 0;
        for (int i = 1; i <= n; i++) {
    
    
            String str = Integer.toString(i);
            for (char c : str.toCharArray()) {
    
    
                if (c == '1') cnt++;
            }
        }
        return cnt;
    }
}

Complexité temporelle: O (nlogn) O (nlogn)
Complexité de l'espace O ( n l o g n ) :O (logn) O (logn)O ( l o g n )

2. Planification dynamique

version 1

Idées:

Référence principale 3, l'analyse spécifique est la suivante:

Le nombre Y est le nombre de X chiffres, chacun des chiffres (un, dix, cent, mille, dix mille ...) est composé de nxnx - 1… n 2 n 1 n_xn_ {x − 1}… n_2n_1nxnx - 1n2n1. parmi eux

  • 1 numéro : cnt;
  • Position actuelle : ni n_inJe, Marqué comme cur;
  • Bit haut : nxnx - 1… ni + 1 n_xn_ {x − 1}… n_ {i + 1}nxnx - 1ni + 1, Marqué comme élevé;
  • Bits faibles : ni - 1… n 2 n 1 n_ {i − 1}… n_2n_1ni - 1n2n1, Marqué comme faible;
  • Facteur binaire : 1 0 i 10 ^ i1 0i , marqué comme facteur.

1. si cur = 0 , alors cnt = high × digit

Par exemple, trouvez les dizaines de 2304, c'est-à-dire lorsque facor = 10, le nombre d'occurrences 1.

2304

另一种推导:十位固定位1
1) 千位选{
    
    01},百位{
    
    01...9},个位{
    
    01...9},cnt = 2*10*10=200;
2) 千位选2,百位{
    
    012},个位{
    
    01...9},cnt = 1*3*10=30;

总计:200+30=230.  可推出公式:cnt  = high×digit

2. si cur = 1 , alors cnt = haut × chiffre + bas + 1

Par exemple, trouvez les dizaines de 2314, c'est-à-dire lorsque facor = 10, le nombre d'occurrences 1.

2314

另一种推导:十位固定位1
1) 千位选{
    
    01},百位{
    
    01...9},个位{
    
    01...9},cnt = 2*10*10=200;
2) 千位选2,     百位{
    
    012},    个位{
    
    01...9},cnt = 1*3*10=30;
3)千位选2,     百位选3,          个位{
    
    01...4},cnt = 5;

总计:200+30+5=235.  可推出公式:cnt  = high×digit+low+1

3. si cur> 1 , alors cnt = (high + 1) × digit

Par exemple, trouvez les dizaines de 2324, c'est-à-dire lorsque facor = 10, le nombre d'occurrences 1.

2324

另一种推导:十位固定位1
1) 千位选{
    
    01},百位{
    
    01...9},个位{
    
    01...9},cnt = 2*10*10=200;
2) 千位选2,     百位{
    
    0123},  个位{
    
    01...9},cnt = 1*4*10=40;

总计:200+40=240.  可推出公式:cnt  = (high+1)×digit

Code:

class Solution {
    
    
    public int countDigitOne(int n) {
    
    
       int res = 0;
       long a = 0;
       long b = 0;
       for(long m=1;m<=n;m*=10){
    
    
           a = n/m;
           b = n%m;
           if(a % 10 > 1){
    
    
               res += a/10 * m + m;
           }else if( a%10 == 1){
    
    
               res += a/10 * m + b + 1;
           }else{
    
    
               res += a/10 * m;
           }
       }
        return res;
    }
}

Complexité temporelle: O (logn) O (logn)
Complexité spatiale O ( l o g n ) :O (1) O (1)O ( 1 )

Version 2

Idée: pour optimiser davantage la formule de dérivation ci-dessus.
Code:

// V1.0
class Solution {
    
    
    public int countDigitOne(int n) {
    
    
        if (n <= 0) return 0;
        long ones = 0;
        for (long i = 1, q = n; i <= n; i *= 10, q /= 10) {
    
    
            long pre = n / (i * 10), cur = q % 10, suf = n % i;
            ones += pre * i;
            ones += (1 < cur ? i : (1 == cur ? suf + 1: 0));
        }
        return (int) ones;
    }
}

// V2.0
class Solution {
    
    
    public int countDigitOne(int n) {
    
    
	    if (n <= 0) return 0;
        int ones = 0;
        for (long m = 1; m <= n; m *= 10)
            ones += (n/m + 8) / 10 * m + (n/m % 10 == 1 ? n%m + 1 : 0);
        return ones;
    }
}

Complexité temporelle: O (logn) O (logn)
Complexité spatiale O ( l o g n ) :O (1) O (1)O ( 1 )

Trois, référence

1. Le nombre de nombres
1 2. 4+ lignes, O (log n), C ++ / Java / Python
3. Question d'entretien 43. Le nombre de 1 à n entiers (illustration claire)
4. Durée: 0 ms, plus rapide que 100,00% de Java en ligne
5. Comparaison de l'efficacité des méthodes int à String et String à int en Java

Je suppose que tu aimes

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