-
Notifications
You must be signed in to change notification settings - Fork 2
/
CountOne.java
92 lines (82 loc) · 2.25 KB
/
CountOne.java
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package org.offer.case32;
/**
* 面试题 32:从 1 到 n 整数中 1 出现的次数
* Created by tanc on 17-6-6.
*/
public class CountOne {
/**
* 方法一:直接遍历
*/
public static int methodOne(int n) {
int result = 0;
for (int i = 1; i <= n; i++) {
result += countOne(i);
}
return result;
}
/**
* 一个数字中 1 的个数
*/
private static int countOne(int n) {
int result = 0;
int num = n;
while (num > 0) {
if (num % 10 == 1) {
result++;
}
num /= 10;
}
return result;
}
/**
* 方法二:寻找规律得出的方法
*/
public static int methodTwo(int n) {
if (n < 0) {
throw new RuntimeException("输入非法");
}
char[] data = String.valueOf(n).toCharArray();
return count(data, 0);
}
private static int count(char[] data, int offset) {
int length = data.length - offset;
int first = parseInt(data[offset]);
if (length == 1 && first == 0) {
return 0;
} else if (length == 1 && first > 0) {
return 1;
}
// 去掉最高位,剩下的位数
int bits = length - 1;
int result = 0;
// 最高位为 0 的情况不用管
if (first == 1) {
int count = parseInt(data, offset + 1);
result += count + 1;
} else if (first > 1) {
result += powerBase10(bits);
}
// 全排列
result += first * bits * powerBase10(bits - 1);
// 递归求次高位
result += count(data, offset + 1);
return result;
}
private static int parseInt(char[] data, int offset) {
int length = data.length - offset;
char[] result = new char[length];
System.arraycopy(data, offset, result, 0, length);
return Integer.parseInt(new String(result));
}
private static int parseInt(char data) {
return data - '0';
}
private static int powerBase10(int n) {
int base = 10;
int result = 1;
for (int i = 0; i < n; i++) {
result *= base;
}
return result;
}
}