-
Notifications
You must be signed in to change notification settings - Fork 0
/
count_of_integers.rs
88 lines (82 loc) · 2.43 KB
/
count_of_integers.rs
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
// 统计整数数目
// https://leetcode.cn/problems/count-of-integers
// INLINE ../../images/math/count_of_integers.jpeg
use std::collections::HashMap;
pub struct Solution;
impl Solution {
pub fn count(num1: String, num2: String, min_sum: i32, max_sum: i32) -> i32 {
let mod_val = 1_000_000_007;
let m = num2.len();
let up_limit: Vec<i32> = num2
.chars()
.map(|c| c.to_digit(10).unwrap() as i32)
.collect();
let down_limit: Vec<i32> = format!("{:0>width$}", num1, width = m)
.chars()
.map(|c| c.to_digit(10).unwrap() as i32)
.collect();
let mut memo: HashMap<(usize, i32, bool, bool, bool), i32> = HashMap::new();
fn f(
i: usize,
s: i32,
valid: bool,
dlimit: bool,
ulimit: bool,
m: usize,
up_limit: &Vec<i32>,
down_limit: &Vec<i32>,
memo: &mut HashMap<(usize, i32, bool, bool, bool), i32>,
mod_val: i32,
min_sum: i32,
max_sum: i32,
) -> i32 {
if i == m {
return if valid && s >= min_sum && s <= max_sum {
1
} else {
0
};
}
let key = (i, s, valid, dlimit, ulimit);
if let Some(&val) = memo.get(&key) {
return val;
}
let down = if dlimit { down_limit[i] } else { 0 };
let up = if ulimit { up_limit[i] } else { 9 };
let mut ans = 0;
for d in down..=up {
ans =
(ans + f(
i + 1,
s + d,
valid || d != 0,
dlimit && d == down,
ulimit && d == up,
m,
up_limit,
down_limit,
memo,
mod_val,
min_sum,
max_sum,
)) % mod_val;
}
memo.insert(key, ans);
ans
}
f(
0,
0,
false,
true,
true,
m,
&up_limit,
&down_limit,
&mut memo,
mod_val,
min_sum,
max_sum,
)
}
}