forked from carpeventus/coding-interviews
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNumOf1.java
More file actions
71 lines (63 loc) · 1.77 KB
/
NumOf1.java
File metadata and controls
71 lines (63 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package Chap5;
/**
* 输入一个整数n,求1~n这n个整数的十进制表示中1出现的次数,
* 例如输入12, 1~12中出现1的有1、10、11、12共5次
*/
public class NumOf1 {
/**
* 方法1,计算每个数字中1的个数,复杂度O(nlgn)
*/
public int NumberOf1From1To(int n) {
// 正负数不影响1的个数,统一变成非负数
if (n < 0) n = Math.abs(n);
int count = 0;
// 循环求n个数字,共O(nlgn)的时间
for (int i = 1; i <= n; i++) {
count += numOf1(i);
}
return count;
}
/**
* O(lgn)的复杂度求一个数中含有1的数量
*/
private int numOf1(int n) {
int count = 0;
while (n != 0) {
if (n % 10 == 1) count++;
n = n / 10;
}
return count;
}
/**
* 方法2:使用StringBuilder将所有数字拼接,无脑数数
*/
public int numOf1Between1AndN(int n) {
// 正负数不影响1的个数,统一变成非负数
if (n < 0) n = Math.abs(n);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(i);
}
int count = 0;
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) == '1') {
count++;
}
}
return count;
}
/**
* 方法三:神一样的方法
*/
public int numberOf1(int n) {
int ones = 0;
for (long m = 1; m <= n; m *= 10) {
long a = n / m;
long b = n % m;
if (a % 10 == 0) ones += a / 10 * m;
else if (a % 10 == 1) ones += (a / 10 * m) + (b + 1);
else ones += (a / 10 + 1) * m;
}
return ones;
}
}