1. Título
Dado un número entero n, cuente el número de apariciones del número 1 en todos los enteros no negativos menores o iguales an.
Ejemplo:
输入: 13
输出: 6
解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13 。
Dos, resolver
1. Agrietamiento por fuerza bruta
Ideas:
Después de leer el tema, puede escribir el código directamente, pero el método se agota .
Código:
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;
}
}
Complejidad de tiempo: O (nlogn) O (nlogn)O ( n l o g n )
complejidad espacial: O (logn) O (logn)O ( l o g n )
2. Planificación dinámica
versión 1
Ideas:
Referencia principal 3, el análisis específico es el siguiente:
El número Y es el número de X dígitos, cada uno de los dígitos (uno, diez, cien, mil, diez mil ...) se compone de nxnx - 1… n 2 n 1 n_xn_ {x − 1}… n_2n_1nortexnortex - 1⋯norte2norte1. entre ellos
- 1 número : cnt;
- Posición actual : ni n_inorteyo, Marcado como cur;
- Bit alto : nxnx - 1… ni + 1 n_xn_ {x − 1}… n_ {i + 1}nortexnortex - 1...nortei + 1, Marcado como alto;
- Bits bajos : ni - 1… n 2 n 1 n_ {i − 1}… n_2n_1nortei - 1...norte2norte1, Marcado como bajo;
- Factor de bits : 1 0 i 10 ^ i1 0i , marcado como factor.
1. si cur = 0, entonces cnt = alto × dígito
Por ejemplo, encuentre las decenas de 2304, es decir, cuando facor = 10, el número de 1 ocurrencias.
另一种推导:十位固定位1
1) 千位选{
0,1},百位{
0,1,...,9},个位{
0,1,...,9},cnt = 2*10*10=200;
2) 千位选2,百位{
0,1,2},个位{
0,1,...,9},cnt = 1*3*10=30;
总计:200+30=230. 可推出公式:cnt = high×digit
2. si cur = 1, entonces cnt = alto × dígito + bajo + 1
Por ejemplo, encuentre las decenas de 2314, es decir, cuando facor = 10, el número de 1 ocurrencias.
另一种推导:十位固定位1
1) 千位选{
0,1},百位{
0,1,...,9},个位{
0,1,...,9},cnt = 2*10*10=200;
2) 千位选2, 百位{
0,1,2}, 个位{
0,1,...,9},cnt = 1*3*10=30;
3)千位选2, 百位选3, 个位{
0,1,...,4},cnt = 5;
总计:200+30+5=235. 可推出公式:cnt = high×digit+low+1
3. si cur> 1, entonces cnt = (alto + 1) × dígito
Por ejemplo, encuentre las decenas de 2324, es decir, cuando facor = 10, el número de 1 ocurrencias.
另一种推导:十位固定位1
1) 千位选{
0,1},百位{
0,1,...,9},个位{
0,1,...,9},cnt = 2*10*10=200;
2) 千位选2, 百位{
0,1,2,3}, 个位{
0,1,...,9},cnt = 1*4*10=40;
总计:200+40=240. 可推出公式:cnt = (high+1)×digit
Código:
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;
}
}
Complejidad de tiempo: O (logn) O (logn)O ( l o g n )
complejidad espacial: O (1) O (1)O ( 1 )
Versión 2
Idea: optimizar aún más la fórmula de derivación anterior.
Código:
// 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;
}
}
Complejidad de tiempo: O (logn) O (logn)O ( l o g n )
complejidad espacial: O (1) O (1)O ( 1 )
Tres, referencia
1. El número del número
1 2. Más de 4 líneas, O (log n), C ++ / Java / Python
3. Pregunta de la entrevista 43. El número de 1 an enteros (ilustración clara)
4. Tiempo de ejecución: 0 ms, más rápido que el 100,00% de Java en línea
5. Comparación de la eficiencia de los métodos int con String y String con int en Java