A program was supposed to print an array of integers. The program forgot to print whitespaces and the array is printed as a string of digits s and all we know is that all integers in the array were in the range [1, k] and there are no leading zeros in the array.
Given the string s and the integer k, return the number of the possible arrays that can be printed assusing the mentioned program. Since the answer may be very large, return it modulo10^9 + 7.
Use recursion and memoization to count the number of ways to split the string into valid numbers in [1, k] with no leading zeros. At each position, try all possible splits and sum the results.
Define a recursive function with memoization that, for each index, tries all possible substrings starting at that index that form valid numbers. For each valid split, recursively count the ways for the remaining substring.
classSolution {
public:int numberOfArrays(string s, int k) {
constint MOD =1e9+7;
int n = s.size();
vector<int> dp(n, -1);
function<int(int)> dfs = [&](int i) {
if (i == n) return1;
if (s[i] =='0') return0;
if (dp[i] !=-1) return dp[i];
int ans =0;
long num =0;
for (int j = i; j < n; ++j) {
num = num *10+ (s[j] -'0');
if (num > k) break;
ans = (ans + dfs(j +1)) % MOD;
}
return dp[i] = ans;
};
returndfs(0);
}
};
classSolution {
publicintnumberOfArrays(String s, int k) {
finalint MOD = 1_000_000_007;
int n = s.length();
Integer[] dp =new Integer[n];
return dfs(s, k, 0, dp, MOD);
}
privateintdfs(String s, long k, int i, Integer[] dp, int MOD) {
if (i == s.length()) return 1;
if (s.charAt(i) =='0') return 0;
if (dp[i]!=null) return dp[i];
int ans = 0;
long num = 0;
for (int j = i; j < s.length(); j++) {
num = num * 10 + s.charAt(j) -'0';
if (num > k) break;
ans = (ans + dfs(s, k, j + 1, dp, MOD)) % MOD;
}
return dp[i]= ans;
}
}
classSolution {
funnumberOfArrays(s: String, k: Int): Int {
val MOD = 1_000_000_007
val n = s.length
val dp = Array<Int?>(n) { null }
fundfs(i: Int): Int {
if (i == n) return1if (s[i] =='0') return0 dp[i]?.let { returnit }
var ans = 0var num = 0Lfor (j in i until n) {
num = num * 10 + (s[j] - '0')
if (num > k) break ans = (ans + dfs(j + 1)) % MOD
}
dp[i] = ans
return ans
}
return dfs(0)
}
}
classSolution:
defnumberOfArrays(self, s: str, k: int) -> int:
MOD =10**9+7 n = len(s)
dp = [-1] * n
defdfs(i):
if i == n:
return1if s[i] =='0':
return0if dp[i] !=-1:
return dp[i]
ans =0 num =0for j in range(i, n):
num = num *10+ int(s[j])
if num > k:
break ans = (ans + dfs(j +1)) % MOD
dp[i] = ans
return ans
return dfs(0)
Instead of recursion, use a DP array where dp[i] is the number of ways to split the substring s[i:] into valid numbers. Fill the array from the end to the start.
Iterate backwards through the string. For each position, try all valid splits (numbers in [1, k] with no leading zeros) and sum the ways from the next position. Use modulo for large results.
classSolution {
public:int numberOfArrays(string s, int k) {
constint MOD =1e9+7;
int n = s.size();
vector<int> dp(n +1);
dp[n] =1;
for (int i = n -1; i >=0; --i) {
if (s[i] =='0') continue;
long num =0;
for (int j = i; j < n; ++j) {
num = num *10+ (s[j] -'0');
if (num > k) break;
dp[i] = (dp[i] + dp[j +1]) % MOD;
}
}
return dp[0];
}
};
classSolution {
publicintnumberOfArrays(String s, int k) {
finalint MOD = 1_000_000_007;
int n = s.length();
int[] dp =newint[n + 1];
dp[n]= 1;
for (int i = n - 1; i >= 0; i--) {
if (s.charAt(i) =='0') continue;
long num = 0;
for (int j = i; j < n; j++) {
num = num * 10 + s.charAt(j) -'0';
if (num > k) break;
dp[i]= (int)((dp[i]+ dp[j + 1]) % MOD);
}
}
return dp[0];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
funnumberOfArrays(s: String, k: Int): Int {
val MOD = 1_000_000_007
val n = s.length
val dp = IntArray(n + 1)
dp[n] = 1for (i in n - 1 downTo 0) {
if (s[i] =='0') continuevar num = 0Lfor (j in i until n) {
num = num * 10 + (s[j] - '0')
if (num > k) break dp[i] = (dp[i] + dp[j + 1]) % MOD
}
}
return dp[0]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution:
defnumberOfArrays(self, s: str, k: int) -> int:
MOD =10**9+7 n = len(s)
dp = [0] * (n +1)
dp[n] =1for i in range(n -1, -1, -1):
if s[i] =='0':
continue num =0for j in range(i, n):
num = num *10+ int(s[j])
if num > k:
break dp[i] = (dp[i] + dp[j +1]) % MOD
return dp[0]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
impl Solution {
pubfnnumber_of_arrays(s: String, k: i32) -> i32 {
constMOD: i32=1_000_000_007;
let n = s.len();
let s = s.as_bytes();
letmut dp =vec![0; n +1];
dp[n] =1;
for i in (0..n).rev() {
if s[i] ==b'0' { continue; }
letmut num =0i64;
for j in i..n {
num = num *10+ (s[j] -b'0') asi64;
if num > k asi64 { break; }
dp[i] = (dp[i] + dp[j +1]) %MOD;
}
}
dp[0]
}
}