forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
number-of-ways-to-separate-numbers.cpp
54 lines (50 loc) · 2.16 KB
/
number-of-ways-to-separate-numbers.cpp
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
// Time: O(n^2)
// Space: O(n^2)
class Solution {
public:
int numberOfCombinations(string num) {
static const int MOD = 1e9 + 7;
const auto& lcp = find_longest_common_prefix(num);
vector<vector<int64_t>> dp(size(num), vector<int64_t>(size(num))); // dp[i][l]: the count of numbers ending at num[i], where the length of the last number is l+1
dp[0][0] = int(num[0] != '0');
for (int i = 1; i < size(num); ++i) {
dp[i][i] = dp[i - 1][i - 1];
if (num[i] == '0') {
continue;
}
for (int l = 1, accu = 0; i + l - 1 < size(num); ++l) {
const int ni = i + l - 1;
dp[ni][l - 1] = accu; // accumulated count where the length of the second to last number ending at num[i-1] is shorter than the length of the last number ending at num[i+l-1]
if (i - l < 0) {
continue;
}
if (num[i - l] != '0' && is_less_or_equal_to_with_same_length(num, lcp, i - l, i, l)) {
dp[ni][l - 1] = (dp[ni][l - 1] + dp[i - 1][l - 1]) % MOD;
}
accu = (accu + dp[i - 1][l - 1]) % MOD;
}
}
return accumulate(cbegin(dp.back()), cend(dp.back()), 0,
[](const auto& a, const auto& b) {
return (a + b) % MOD;
});
}
private:
vector<vector<int64_t>> find_longest_common_prefix(const string& num) {
vector<vector<int64_t>> lcp(size(num) + 1, vector<int64_t>(size(num) + 1)); // lcp[i][j]: longest length of the common prefix which starts at num[i], num[j]
for (int i = size(lcp) - 2; i >= 0; --i) {
for (int j = size(lcp[i]) - 2; j >= 0; --j) {
if (num[i] == num[j]) {
lcp[i][j] = lcp[i + 1][j + 1] + 1;
}
}
}
return lcp;
}
bool is_less_or_equal_to_with_same_length(
const string& num,
const vector<vector<int64_t>>& lcp,
int i, int j, int l) {
return lcp[i][j] >= l || num[i + lcp[i][j]] < num[j + lcp[i][j]];
}
};