Problem
Given two positive integers low
and high
represented as strings, find the count of stepping numbers in the inclusive range [low, high]
.
A stepping number is an integer such that all of its adjacent digits have an absolute difference of exactly 1
.
Return an integer denoting the count of stepping numbers in the inclusive range [low, high]
**. **
Since the answer may be very large, return it modulo 109 + 7
.
Note: A stepping number should not have a leading zero.
Example 1:
Input: low = "1", high = "11"
Output: 10
Explanation: The stepping numbers in the range [1,11] are 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10. There are a total of 10 stepping numbers in the range. Hence, the output is 10.
Example 2:
Input: low = "90", high = "101"
Output: 2
Explanation: The stepping numbers in the range [90,101] are 98 and 101. There are a total of 2 stepping numbers in the range. Hence, the output is 2.
Constraints:
1 <= int(low) <= int(high) < 10100
1 <= low.length, high.length <= 100
low
andhigh
consist of only digits.low
andhigh
don't have any leading zeros.
Solution (Java)
class Solution {
private static final int mod = 1000000007;
private long[][][][] dp;
public int countSteppingNumbers(final String low, final String high) {
resetArray();
long result = solve(high, 0, -1, 1, 1);
resetArray();
result -= solve(low, 0, -1, 1, 1);
result = (result + mod) % mod;
int lowIsValid = getLowIsValid(low);
result = (result + mod + lowIsValid) % mod;
return (int) result;
}
private int getLowIsValid(final String low) {
int lowIsValid = 1;
for (int i = 1; i < low.length(); i++)
if (Math.abs(low.charAt(i) - low.charAt(i - 1)) != 1) {
lowIsValid = 0;
break;
}
return lowIsValid;
}
private long solve(final String numString, int currentIndex, int previousDigit, int bound, int isZero) {
if (numString.length() == currentIndex) return 1 - isZero;
if (dp[currentIndex][previousDigit + 1][isZero][bound] != -1)
return dp[currentIndex][previousDigit + 1][isZero][bound];
long limit = numString.charAt(currentIndex) - '0';
if (bound == 0) limit = 9;
long ans = 0;
for (int currentDigit = 0; currentDigit <= limit; currentDigit++) {
int nextBound = (bound == 1 && currentDigit == limit) ? 1 : 0;
int nextZero = (isZero == 1 && currentDigit == 0) ? 1 : 0;
if (isZero == 1 || Math.abs(currentDigit - previousDigit) == 1)
ans += (solve(numString, currentIndex + 1, currentDigit, nextBound, nextZero)) % mod;
}
return dp[currentIndex][previousDigit + 1][isZero][bound] = ans;
}
private void resetArray() {
dp = new long[101][11][2][2];
for (var i : dp) for (var j : i) for (var k : j) Arrays.fill(k, -1);
}
}
Explain:
nope.
Complexity:
- Time complexity : O(n).
- Space complexity : O(n).