class Solution:
def countNumbersWithUniqueDigits(self, n: int) -> int:
if n == 0:
return 1
count = 10
uniqueDigits = 9
availableNumber = 9
for i in range(2, n+1):
uniqueDigits *= availableNumber
count += uniqueDigits
availableNumber -= 1
if availableNumber == 0:
break
return count
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
int count = 10, uniqueDigits = 9, availableNumber = 9;
for (int i = 2; i <= n; ++i) {
uniqueDigits *= availableNumber;
count += uniqueDigits;
--availableNumber;
if (availableNumber == 0) break;
}
return count;
}
};
class Solution {
public int countNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
int count = 10, uniqueDigits = 9, availableNumber = 9;
for (int i = 2; i <= n; ++i) {
uniqueDigits *= availableNumber;
count += uniqueDigits;
availableNumber--;
if (availableNumber == 0) break;
}
return count;
}
}
var countNumbersWithUniqueDigits = function(n) {
if (n === 0) return 1;
let count = 10, uniqueDigits = 9, availableNumber = 9;
for (let i = 2; i <= n; ++i) {
uniqueDigits *= availableNumber;
count += uniqueDigits;
availableNumber--;
if (availableNumber === 0) break;
}
return count;
};
You are given a non-negative integer n
. Your task is to count how many numbers with unique digits exist in the range [0, 10n)
. In other words, for each integer x
such that 0 ≤ x < 10n
, count it if and only if every digit in x
is distinct (no digit repeats).
n = 2
, you should count all numbers from 0
to 99
with no repeated digits (e.g., 11
is invalid).0 ≤ n ≤ 8
.01
is counted as 1
).
The first idea that comes to mind is brute-forcing through all numbers from 0
to 10n - 1
and checking if each number has unique digits. While this works for small n
, it quickly becomes infeasible for large n
because the number of possibilities grows exponentially.
Instead, we realize that the problem is about counting, not generating, so we can use combinatorics. For each possible number length (from 1 up to n
), we can count how many numbers of that length have all unique digits. We sum those counts to get the final answer.
The key insight is that for each digit position, we must pick a digit that hasn't been used yet. For example, the first digit can't be zero (except for the number zero itself), and each subsequent digit must be different from the previous ones.
n = 0
, the only valid number is 0
, so the answer is 1
.
10
numbers (from 0
to 9
), all with unique digits.
1-9
(9 choices), the second digit can be any of the remaining 9 digits (including 0, but not the first digit), so 9 * 9 = 81
.
9 * 9 * 8 = 648
.
count = 10
for n ≥ 1
.n
:
count
.
This approach leverages permutations and avoids brute-force enumeration, making it efficient even for larger n
.
Let's walk through the process for n = 2
:
10
numbers: 0
to 9
.
1-9
(9
choices).0-9
except the first digit (9
choices).9 * 9 = 81
10 + 81 = 91
0
to 99
are considered. Numbers like 11
, 22
, etc., are not counted because they repeat digits.
[0, 10^n)
, check if its digits are unique. This is O(10^n * n)
, which becomes infeasible quickly as n
increases.
n
(at most 8), and for each, perform a constant number of multiplications. So the time complexity is O(n)
.
O(1)
extra space (no large data structures).
The problem asks for the count of numbers with all unique digits in the range [0, 10^n)
. While brute-force is possible for small n
, leveraging combinatorics provides a much more efficient solution. By counting the number of ways to build numbers of each length with unique digits, we avoid unnecessary computation. The approach is elegant because it uses mathematical reasoning over enumeration, making it both efficient and easy to implement.