You're given two integers l and r represented as strings, and an integer b (the base). Your task is to count how many integers in the inclusive range [l, r] have non-decreasing digits when represented in base b.
A number has non-decreasing digits if, when reading from left to right (most significant to least significant digit), each digit is greater than or equal to the previous digit.
Example: In base 10, the number 1234 has non-decreasing digits (1 ≤ 2 ≤ 3 ≤ 4), but 4321 does not (4 > 3 > 2 > 1).
Since the answer can be very large, return it modulo 109 + 7.
This problem combines number theory, dynamic programming, and digit manipulation - making it a favorite in technical interviews!
Input & Output
example_1.py — Basic Range in Base 10
$Input:l = "1", r = "9", b = 10
›Output:9
💡 Note:All single digits (1,2,3,4,5,6,7,8,9) have non-decreasing digits trivially, so the answer is 9.
example_2.py — Two-digit Range
$Input:l = "10", r = "15", b = 10
›Output:3
💡 Note:Numbers 11, 12, 13 have non-decreasing digits. Numbers 10, 14, 15 do not (1>0, 1<4 but then 4>5, 1<5 but we need to check: 10→digits[1,0]→1>0❌, 14→[1,4]→1≤4✅, 15→[1,5]→1≤5✅). So valid numbers are 11,12,13,14,15 = 5. Wait, let me recalculate: 10→[1,0]→invalid, 11→[1,1]→valid, 12→[1,2]→valid, 13→[1,3]→valid, 14→[1,4]→valid, 15→[1,5]→valid. Answer is 5.
example_3.py — Different Base
$Input:l = "1", r = "10", b = 2
›Output:3
💡 Note:In base 2, we check numbers 1-10 (decimal). 1→[1]✅, 2→[1,0]❌, 3→[1,1]✅, 4→[1,0,0]❌, 5→[1,0,1]❌, 6→[1,1,0]❌, 7→[1,1,1]✅, 8→[1,0,0,0]❌, 9→[1,0,0,1]❌, 10→[1,0,1,0]❌. Valid: 1,3,7. Answer is 3.
Constraints
1 ≤ l ≤ r ≤ 1015
2 ≤ b ≤ 36
l and r are given as decimal strings
Answer must be returned modulo 109 + 7
Visualization
Tap to expand
Understanding the Visualization
1
Initialize DP State
Start with position 0, no previous digit constraint, and tight bounds for both l and r
2
Choose Valid Digits
At each position, try all digits that satisfy: digit ≥ previous_digit and within bounds
3
Update Constraints
Update tight bounds and previous digit for the next recursive call
4
Count Valid Paths
Sum up all paths that lead to valid numbers within the range
Key Takeaway
🎯 Key Insight: Use Dynamic Programming to mathematically count valid digit patterns instead of checking every single number in the range - this transforms an O(r-l) brute force into an O(d² × b) elegant solution!
Count Numbers with Non-Decreasing Digits — Solution
This problem is optimally solved using Dynamic Programming with Digit Constraints (Digit DP). Instead of checking every number in the range [l,r], we mathematically count valid numbers by building them digit by digit while maintaining the non-decreasing constraint and boundary conditions. The key insight is to use memoized recursion with states tracking position, previous digit, and tight bounds, achieving O(d² × b) complexity where d is the number of digits.
Common Approaches
Approach
Time
Space
Notes
✓
Dynamic Programming with Digit Constraints
O(d² × b)
O(d² × b)
Use digit DP to count valid numbers by building them digit by digit with constraints
Dynamic Programming with Digit Constraints — Algorithm Steps
Convert l and r to base b digit arrays
Use memoized recursion with state (position, previous_digit, tight_l, tight_r, started)
At each position, try all valid digits that maintain non-decreasing property