Skip to content

Commit 2bb0321

Browse files
committed
feat: add solutions to lc problem: No.0233.Number of Digit One
1 parent 1ca9cf2 commit 2bb0321

File tree

4 files changed

+276
-2
lines changed

4 files changed

+276
-2
lines changed

solution/0200-0299/0233.Number of Digit One/README.md

+107-1
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,128 @@
3737

3838
<!-- 这里可写通用的实现逻辑 -->
3939

40+
经典数位 dp 问题,也可以用找规律解决
41+
4042
<!-- tabs:start -->
4143

4244
### **Python3**
4345

4446
<!-- 这里可写当前语言的特殊实现逻辑 -->
4547

4648
```python
47-
49+
class Solution:
50+
def countDigitOne(self, n: int) -> int:
51+
dp = [[-1] * 10 for _ in range(10)]
52+
digit = []
53+
while n:
54+
digit.append(n % 10)
55+
n //= 10
56+
57+
def dfs(pos: int, cnt: int, limit: bool) -> int:
58+
if pos == -1: return cnt
59+
if not limit and dp[pos][cnt] != -1: return dp[pos][cnt]
60+
up = digit[pos] if limit else 9
61+
ans = 0
62+
for i in range(up + 1):
63+
nxt = cnt + 1 if i == 1 else cnt
64+
ans += dfs(pos - 1, nxt, limit and i == digit[pos])
65+
if not limit: dp[pos][cnt] = ans
66+
return ans
67+
68+
return dfs(len(digit) - 1, 0, True)
4869
```
4970

5071
### **Java**
5172

5273
<!-- 这里可写当前语言的特殊实现逻辑 -->
5374

5475
```java
76+
class Solution {
77+
public int countDigitOne(int n) {
78+
int index = 1;
79+
int count = 0;
80+
int high = n,cur = 0,low = 0;
81+
while(high > 0){
82+
high /= 10;
83+
cur = (n / index) % 10;
84+
low = n - (n / index) * index;
85+
if(cur == 0) count += high * index;
86+
if(cur == 1) count += high * index + low + 1;
87+
if(cur > 1) count += (high+1) * index;
88+
index *= 10;
89+
}
90+
return count;
91+
}
92+
}
93+
```
94+
95+
### **C#**
96+
97+
```cs
98+
public class Solution {
99+
public int CountDigitOne(int n) {
100+
if (n <= 0) return 0;
101+
if (n < 10) return 1;
102+
return CountDigitOne(n / 10 - 1) * 10 + n / 10 + CountDigitOneOfN(n / 10) * (n % 10 + 1) + (n % 10 >= 1 ? 1 : 0);
103+
}
104+
105+
private int CountDigitOneOfN(int n) {
106+
var count = 0;
107+
while (n > 0)
108+
{
109+
if (n % 10 == 1) ++count;
110+
n /= 10;
111+
}
112+
return count;
113+
}
114+
}
115+
```
55116

117+
### **Go**
118+
119+
```go
120+
func countDigitOne(n int) int {
121+
digit := make([]int, 0)
122+
for i := n; i > 0; i /= 10 {
123+
digit = append(digit, i%10)
124+
}
125+
126+
dp := make([][]int, 10)
127+
for i := range dp {
128+
dp[i] = make([]int, 10)
129+
for j := 0; j < 10; j++ {
130+
dp[i][j] = -1
131+
}
132+
}
133+
134+
var dfs func(pos, cnt int, limit bool) int
135+
dfs = func(pos, cnt int, limit bool) int {
136+
if pos == -1 {
137+
return cnt
138+
}
139+
if !limit && dp[pos][cnt] != -1 {
140+
return dp[pos][cnt]
141+
}
142+
up := 9
143+
if limit {
144+
up = digit[pos]
145+
}
146+
ans := 0
147+
for i := 0; i <= up; i++ {
148+
next := cnt
149+
if i == 1 {
150+
next++
151+
}
152+
ans += dfs(pos-1, next, limit && i == digit[pos])
153+
}
154+
if !limit {
155+
dp[pos][cnt] = ans
156+
}
157+
return ans
158+
}
159+
160+
return dfs(len(digit)-1, 0, true)
161+
}
56162
```
57163

58164
### **...**

solution/0200-0299/0233.Number of Digit One/README_EN.md

+107-1
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,124 @@
3131

3232
## Solutions
3333

34+
simple digital dp problem (or it can be solved by finding a rule)
35+
3436
<!-- tabs:start -->
3537

3638
### **Python3**
3739

3840
```python
39-
41+
class Solution:
42+
def countDigitOne(self, n: int) -> int:
43+
dp = [[-1] * 10 for _ in range(10)]
44+
digit = []
45+
while n:
46+
digit.append(n % 10)
47+
n //= 10
48+
49+
def dfs(pos: int, cnt: int, limit: bool) -> int:
50+
if pos == -1: return cnt
51+
if not limit and dp[pos][cnt] != -1: return dp[pos][cnt]
52+
up = digit[pos] if limit else 9
53+
ans = 0
54+
for i in range(up + 1):
55+
nxt = cnt + 1 if i == 1 else cnt
56+
ans += dfs(pos - 1, nxt, limit and i == digit[pos])
57+
if not limit: dp[pos][cnt] = ans
58+
return ans
59+
60+
return dfs(len(digit) - 1, 0, True)
4061
```
4162

4263
### **Java**
4364

4465
```java
66+
class Solution {
67+
public int countDigitOne(int n) {
68+
int index = 1;
69+
int count = 0;
70+
int high = n,cur = 0,low = 0;
71+
while(high > 0){
72+
high /= 10;
73+
cur = (n / index) % 10;
74+
low = n - (n / index) * index;
75+
if(cur == 0) count += high * index;
76+
if(cur == 1) count += high * index + low + 1;
77+
if(cur > 1) count += (high+1) * index;
78+
index *= 10;
79+
}
80+
return count;
81+
}
82+
}
83+
```
84+
85+
### **C#**
86+
87+
```cs
88+
public class Solution {
89+
public int CountDigitOne(int n) {
90+
if (n <= 0) return 0;
91+
if (n < 10) return 1;
92+
return CountDigitOne(n / 10 - 1) * 10 + n / 10 + CountDigitOneOfN(n / 10) * (n % 10 + 1) + (n % 10 >= 1 ? 1 : 0);
93+
}
94+
95+
private int CountDigitOneOfN(int n) {
96+
var count = 0;
97+
while (n > 0)
98+
{
99+
if (n % 10 == 1) ++count;
100+
n /= 10;
101+
}
102+
return count;
103+
}
104+
}
105+
```
45106

107+
### **Go**
108+
109+
```go
110+
func countDigitOne(n int) int {
111+
digit := make([]int, 0)
112+
for i := n; i > 0; i /= 10 {
113+
digit = append(digit, i%10)
114+
}
115+
116+
dp := make([][]int, 10)
117+
for i := range dp {
118+
dp[i] = make([]int, 10)
119+
for j := 0; j < 10; j++ {
120+
dp[i][j] = -1
121+
}
122+
}
123+
124+
var dfs func(pos, cnt int, limit bool) int
125+
dfs = func(pos, cnt int, limit bool) int {
126+
if pos == -1 {
127+
return cnt
128+
}
129+
if !limit && dp[pos][cnt] != -1 {
130+
return dp[pos][cnt]
131+
}
132+
up := 9
133+
if limit {
134+
up = digit[pos]
135+
}
136+
ans := 0
137+
for i := 0; i <= up; i++ {
138+
next := cnt
139+
if i == 1 {
140+
next++
141+
}
142+
ans += dfs(pos-1, next, limit && i == digit[pos])
143+
}
144+
if !limit {
145+
dp[pos][cnt] = ans
146+
}
147+
return ans
148+
}
149+
150+
return dfs(len(digit)-1, 0, true)
151+
}
46152
```
47153

48154
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
func countDigitOne(n int) int {
2+
digit := make([]int, 0)
3+
for i := n; i > 0; i /= 10 {
4+
digit = append(digit, i%10)
5+
}
6+
7+
dp := make([][]int, 10)
8+
for i := range dp {
9+
dp[i] = make([]int, 10)
10+
for j := 0; j < 10; j++ {
11+
dp[i][j] = -1
12+
}
13+
}
14+
15+
var dfs func(pos, cnt int, limit bool) int
16+
dfs = func(pos, cnt int, limit bool) int {
17+
if pos == -1 {
18+
return cnt
19+
}
20+
if !limit && dp[pos][cnt] != -1 {
21+
return dp[pos][cnt]
22+
}
23+
up := 9
24+
if limit {
25+
up = digit[pos]
26+
}
27+
ans := 0
28+
for i := 0; i <= up; i++ {
29+
next := cnt
30+
if i == 1 {
31+
next++
32+
}
33+
ans += dfs(pos-1, next, limit && i == digit[pos])
34+
}
35+
if !limit {
36+
dp[pos][cnt] = ans
37+
}
38+
return ans
39+
}
40+
41+
return dfs(len(digit)-1, 0, true)
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution:
2+
def countDigitOne(self, n: int) -> int:
3+
dp = [[-1] * 10 for _ in range(10)]
4+
digit = []
5+
while n:
6+
digit.append(n % 10)
7+
n //= 10
8+
9+
def dfs(pos: int, cnt: int, limit: bool) -> int:
10+
if pos == -1: return cnt
11+
if not limit and dp[pos][cnt] != -1: return dp[pos][cnt]
12+
up = digit[pos] if limit else 9
13+
ans = 0
14+
for i in range(up + 1):
15+
nxt = cnt + 1 if i == 1 else cnt
16+
ans += dfs(pos - 1, nxt, limit and i == digit[pos])
17+
if not limit: dp[pos][cnt] = ans
18+
return ans
19+
20+
return dfs(len(digit) - 1, 0, True)

0 commit comments

Comments
 (0)