Last Updated: March 28, 2026
We are given a set of allowed digits (each between '1' and '9'), and we need to count how many positive integers up to n can be formed using only those digits. Each digit can be reused as many times as we want. So if digits = ["1","3"], we can form 1, 3, 11, 13, 31, 33, 111, 113, and so on.
The key insight is that this is really a counting problem with two distinct parts. First, any number with fewer digits than n is automatically less than n, so we can count all of those easily. Second, for numbers with the same number of digits as n, we need to carefully count only those that do not exceed n. This second part is where the problem gets interesting, and it is a classic application of digit dynamic programming.
1 <= n <= 10^9 → n has at most 10 digits. Any approach that processes digit-by-digit is very efficient.1 <= digits.length <= 9 → The digit set is small. We can iterate over it freely at each position.digits[i] is from '1' to '9' → No zero in the digit set. This simplifies things because every combination of allowed digits forms a valid positive integer (no leading zero issues).The simplest approach is to generate every possible number from the allowed digits and check if it is at most n. We can do this with BFS: start with each allowed digit, then repeatedly append allowed digits to build longer numbers.
This is straightforward but extremely slow for large n. If digits = ["1","3","5","7"] and n = 10^9, we could potentially generate millions of numbers.
This approach generates every valid number, which is far too slow for large inputs. Instead of enumerating, can we count valid numbers mathematically?
Instead of generating numbers one by one, we can count them mathematically. The key observation splits the problem into two parts.
Part 1: Numbers with fewer digits than n. If n has L digits, then any valid number with 1 digit, 2 digits, ..., or L-1 digits is automatically less than n. For k-digit numbers, each of the k positions can be any of the d allowed digits (since none of them is '0', there is no leading-zero issue). So there are d^k valid numbers of exactly k digits.
Part 2: Numbers with exactly L digits. We process the digits of n from left to right. At each position i, we ask: how many allowed digits are strictly less than n's digit at position i? Each of those lets us fill the remaining positions freely. Is n's digit at position i itself in the allowed set? If yes, we match it and continue. If no, we stop.
If we successfully match every digit of n, then n itself is a valid number, so we add 1.
We are partitioning all valid numbers into non-overlapping groups. First, we count all numbers that are shorter than n, which are automatically smaller. Then for same-length numbers, we sweep from the most significant digit to the least. At each position, numbers that have already "committed" to being smaller (by choosing a smaller digit at some position) can freely fill the remaining positions. Numbers that match n's digit exactly remain "tied" and need further examination. This is the fundamental principle behind digit counting problems.
less.less * d^(L-1-i) to count.This approach uses floating-point Math.pow which can cause precision issues. Can we precompute powers with integer arithmetic and express the solution as a clean DP?
We can reformulate this as a dynamic programming problem that processes n from right to left. Define dp[i] as the number of valid numbers that can be formed considering positions i through L-1 of n, under the constraint that the prefix so far exactly matches n.
The recurrence works as follows: for each allowed digit less than S[i], we can fill the remaining positions freely (contributing d^(L-1-i)). For each allowed digit equal to S[i], the answer depends on dp[i+1]. Digits greater than S[i] contribute nothing.
The base case is dp[L] = 1, meaning if we have matched all digits of n exactly, we count n itself. We still add the counts for numbers shorter than n separately.
The DP formulation captures the exact same logic as Approach 2 but in a cleaner, more formal structure. The key insight is that dp[i] represents the number of valid completions from position i onward, given that positions 0 through i-1 have exactly matched n. When a digit is smaller than S[i], all subsequent positions are unconstrained, giving d^(L-1-i) choices. When it equals S[i], the constraint carries forward, captured by dp[i+1]. This bottom-up formulation avoids floating-point arithmetic entirely and makes the logic easy to verify.
pow[i] = d^i for i from 0 to L using integer arithmetic.dp[L] = 1 (base case: matched all digits of n).pow[L-1-i].dp[i+1].dp[0].pow[1] through pow[L-1].