Skip to content

Commit f3b3830

Browse files
committed
feat: add python and java solutions to lcof question
添加《剑指 Offer》题解:面试题43. 1~n整数中1出现的次数
1 parent 14a4f8e commit f3b3830

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

lcof/面试题43. 1~n整数中1出现的次数/README.md

+41-2
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,59 @@
2828

2929
## 解法
3030
<!-- 这里可写通用的实现逻辑 -->
31+
将 n 拆为两部分:最高位 high 和低位 lows。按 high 是否为 1 分别递归求解结果 f(n)。
3132

33+
举例说明。
34+
35+
n=3356: high=3,lows=356,base=1000
36+
37+
此时数字划分为 0~999,1000~1999,2000~2999,3000~3356,其中:
38+
39+
- 0~999 这个范围内 1 的个数为 f(base-1)
40+
- 1000~1999 这个范围内 1 的个数可分为两部分:千位、其余位。千位都为 1,所以 1 的个数为 base+f(base-1)
41+
- 2000~2999 这个范围内 1 的个数为 f(base-1)
42+
- 3000~3356 这个范围内 1 的个数为 f(lows)
43+
44+
因此,1 的总个数为 `high*f(base-1)+f(lows)+base`
45+
46+
最高位非 1 的情况,也可以按照同样的方法分析。
3247

3348
### Python3
3449
<!-- 这里可写当前语言的特殊实现逻辑 -->
3550

3651
```python
37-
52+
from functools import lru_cache
53+
54+
class Solution:
55+
@lru_cache
56+
def countDigitOne(self, n: int) -> int:
57+
if n < 1:
58+
return 0
59+
s = str(n)
60+
high = int(s[0])
61+
base = pow(10, len(s) - 1)
62+
lows = n % base
63+
return self.countDigitOne(base - 1) + lows + 1 + self.countDigitOne(lows) if high == 1 else high * self.countDigitOne(base - 1) + base + self.countDigitOne(lows)
3864
```
3965

4066
### Java
4167
<!-- 这里可写当前语言的特殊实现逻辑 -->
4268

4369
```java
44-
70+
class Solution {
71+
public int countDigitOne(int n) {
72+
if (n < 1) {
73+
return 0;
74+
}
75+
String s = String.valueOf(n);
76+
int high = s.charAt(0) - '0'; // 最高位
77+
int base = (int) Math.pow(10, s.length() - 1); // 基数
78+
int lows = n % base; // 低位
79+
return high == 1
80+
? countDigitOne(base - 1) + countDigitOne(lows) + lows + 1
81+
: high * countDigitOne(base - 1) + countDigitOne(lows) + base;
82+
}
83+
}
4584
```
4685

4786
### ...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution {
2+
public int countDigitOne(int n) {
3+
if (n < 1) {
4+
return 0;
5+
}
6+
String s = String.valueOf(n);
7+
int high = s.charAt(0) - '0'; // 最高位
8+
int base = (int) Math.pow(10, s.length() - 1); // 基数
9+
int lows = n % base; // 低位
10+
return high == 1
11+
? countDigitOne(base - 1) + countDigitOne(lows) + lows + 1
12+
: high * countDigitOne(base - 1) + countDigitOne(lows) + base;
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from functools import lru_cache
2+
3+
class Solution:
4+
@lru_cache
5+
def countDigitOne(self, n: int) -> int:
6+
if n < 1:
7+
return 0
8+
s = str(n)
9+
high = int(s[0])
10+
base = pow(10, len(s) - 1)
11+
lows = n % base
12+
return self.countDigitOne(base - 1) + lows + 1 + self.countDigitOne(lows) if high == 1 else high * self.countDigitOne(base - 1) + base + self.countDigitOne(lows)

0 commit comments

Comments
 (0)