LeetCode Count Numbers with Unique Digits

LeetCode Count Numbers with Unique Digits

Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n.

Example:
Given n = 2, return 91. (The answer should be the total numbers in the range of 0 ≤ x < 100, excluding [11,22,33,44,55,66,77,88,99])

Hint:

  1. A direct way is to use the backtracking approach.
  2. Backtracking should contains three states which are (the current number, number of steps to get that number and a bitmask which represent which number is marked as visited so far in the current number). Start with state (0,0,0) and count all valid number till we reach number of steps equals to 10n.
  3. This problem can also be solved using a dynamic programming approach and some knowledge of combinatorics.
  4. Let f(k) = count of numbers with unique digits with length equals k.
  5. f(1) = 10, ..., f(k) = 9 * 9 * 8 * ... (9 - k + 2) [The first factor is 9 because a number cannot start with 0].

给定n,问在[0,10n)内有多少个每一位都是不同数字的数。比如当n=2时,在[0,100)内,有91个这样的数,需要排除个位和十位数字相同的9个数。

其实这个题很简单,假设k表示数的位数,找一下规律:

  • k=1,一位数,可以填入0~9这10个数,结果为10
  • k=2,两位数,十位填入1~9这9个数,个位填入0~9中除了十位的那个数字,有9种情况,结果为9*9
  • k=3,三位数,百位填入1~9这9个数字,十位填入0~9中除了百位的那个数字,有9种情况,个位填入0~9中除了百位和十位的那两个数字,有8种情况,结果为9*9*8
  • ...
  • k=n,结果为9*9*8*...*(9-n+2)

所以我们可以用DP解题,f(k)=f(k-1)*(9-k+2),为了节省空间,只需保存上一次的结果f(k-1)。在DP的过程中,累加f(k)的结果。

代码如下:

class Solution {
public:
	int countNumbersWithUniqueDigits(int n) {
		if (n == 0)return 1;
		if (n == 1)return 10;
		int ans = 10, last = 9;
		for (int i = 2; i <= n; ++i) {
			last *= (9 - i + 2);
			ans += last;
		}
		return ans;
	}
};

本代码提交AC,用时3MS。

Leave a Reply

Your email address will not be published. Required fields are marked *