Problem Description
Given a positive integer n, count how many numbers in the range [1, n] are "special" (i.e. all digits within the number are distinct).
Key Insights
- The problem is effectively about counting numbers with distinct digits.
- For numbers with fewer digits than n, we can employ combinatorial counting.
- For numbers with the same number of digits as n, a digit dynamic programming (DP) approach is used to count valid numbers without over-counting.
- A state in the DP typically tracks the current position, whether we are bound by the prefix of n (tight condition), and which digits have already been used (using a bitmask).
- Since n ≤ 2×10^9, the maximum digit length is 10, which helps keep the DP state space manageable.
Space and Time Complexity
Time Complexity: O(10 * 2^10) (since the state space is bounded by the positions, used digits with a bitmask, and the tight constraint). Space Complexity: O(10 * 2^10) due to the memoization cache, which is effectively constant space with respect to n.
Solution
We solve the problem in two parts:
- Count numbers with distinct digits that have fewer digits than n using combinatorial methods.
- Count numbers with the same number of digits as n using a digit DP approach.
For the DP part:
- Use a recursive function that processes one digit at a time.
- Keep track of whether the current prefix matches the prefix of n (tight bound).
- Use a bitmask to record which digits have been used so far.
- For each digit, if the tight condition holds, restrict the available digits to those not greater than the corresponding digit in n.
- Handle the case of leading zeros carefully (they are not allowed in normal non-zero numbers).
The trickiest part is managing the tight constraint and ensuring that once the current number becomes smaller than that of n (i.e., relaxed), we can freely choose any unused digit for subsequent positions using combinatorial counting.