[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].

Credits:
Special thanks to @memoryless for adding this problem and creating all test cases.

这道题让我们找一个范围内的各位上不相同的数字,比如123就是各位不相同的数字,而11,121,222就不是这样的数字。那么我们根据提示中的最后一条可以知道,一位数的满足要求的数字是10个(0到9),二位数的满足题意的是81个,[10 - 99]这90个数字中去掉[11,22,33,44,55,66,77,88,99]这9个数字,还剩81个。通项公式为f(k) = 9 * 9 * 8 * ... (9 - k + 2),那么我们就可以根据n的大小,把[1, n]区间位数通过通项公式算出来累加起来即可,参见代码如下:

解法一:

class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        if (n == 0) return 1;
        int res = 0;
        for (int i = 1; i <= n; ++i) {
            res += count(i);
        }
        return res;
    }
    int count(int k) {
        if (k < 1) return 0;
        if (k == 1) return 10;
        int res = 1;
        for (int i = 9; i >= (11 - k); --i) {
            res *= i;
        }
        return res * 9;
    }
};

下面这种方法是上面方法的精简版,思路完全一样:

解法二:

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

最后我们来看题目提示中所说的回溯的方法,我们需要一个变量used,其二进制第i位为1表示数字i出现过,刚开始我们遍历1到9,对于每个遍历到的数字,现在used中标记已经出现过,然后在调用递归函数。在递归函数中,如果这个数字小于最大值,则结果res自增1,否则返回res。然后遍历0到9,如果当前数字没有在used中出现过,此时在used中标记,然后给当前数字乘以10加上i,再继续调用递归函数,这样我们可以遍历到所有的情况,参见代码如下:

解法三:

class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        int res = 1, max = pow(10, n), used = 0;
        for (int i = 1; i < 10; ++i) {
            used |= (1 << i);
            res += search(i, max, used);
            used &= ~(1 << i);
        }
        return res;
    }
    int search(int pre, int max, int used) {
        int res = 0;
        if (pre < max) ++res;
        else return res;
        for (int i = 0; i < 10; ++i) {
            if (!(used & (1 << i))) {
                used |= (1 << i);
                int cur = 10 * pre + i;
                res += search(cur, max, used);
                used &= ~(1 << i);
            }
        }
        return res;
    }
};

参考资料:

https://leetcode.com/discuss/107981/backtracking-solution

https://leetcode.com/discuss/108119/java-concise-dp-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

时间: 2024-10-26 10:57:29

[LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数的相关文章

357 Count Numbers with Unique Digits 计算各个位数不同的数字个数

给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n.示例:给定 n = 2,返回 91.(答案应该是除[11,22,33,44,55,66,77,88,99]外,0 ≤ x < 100 间的所有数字) 详见:https://leetcode.com/problems/count-numbers-with-unique-digits/description/ C++: class Solution { public: int countNumbersWith

leetCode 357. Count Numbers with Unique Digits | Dynamic Programming | Medium

357. 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,3

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 d

【Leetcode】Count Numbers with Unique Digits

题目链接:https://leetcode.com/problems/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

[Swift]LeetCode357. 计算各个位数不同的数字个数 | Count Numbers with Unique Digits

Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Example: Input: 2 Output: 91 Explanation: The answer should be the total numbers in the range of 0 ≤ x < 100,   excluding 11,22,33,44,55,66,77,88,99 给定一个非负整数

Java [Leetcode 357]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]) 解题思路: This

【leetcode】357. Count Numbers with Unique Digits

题目描述: Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. 解题分析: 题目要就就是找出 0≤ x < 10n中各位数字都不相同的数的个数.要接触这道题只需要理解: 1.设f(n)表示n为数字中各位都不相同的个数,则有countNumbersWithUniqueDigits(n)=f(1)+f(2)+……+f(n)=f(n)+countNumbersWithU

Count Numbers with Unique Digits -- LeetCode

Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10^n. 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]) 思路:DP dp[i]表示10

357. 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]) Credits:Special