[LeetCode] 357. Count Numbers with Unique Digits

Problem:

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])


Solution:

class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        if (n == 0) return 1;
        int res = 10; // n = 1时结果为10
        int base = 9;
        // 归为简单的组合问题
        for (int i = 2; i <= n; i++) {
            /*n = 2时,仅考虑两位数,结果为9 x 9 = 81(首位不能为0,末位可以为0)
              n = 3时,仅考虑三位数,结果为9 x 9 x 8
              ...
              以此类推*/
            
            base *= (9-i+2);
            res += base;
        }
        return res;
    }
};

推导过程分析:

1. 所有一位数均符合条件 -> 10个

2. 考虑所有两位数,十位不能为0,有1-9九个选择,各位不能与十位相同(但可以为0),符合条件

    的数有9 x 9 = 81个;

3. 考虑所有三位数,第三位不能和前两位相同,所以仅有8种选择,符合条件的三位数有9 x 9 x 8个;

4. 考虑所有n(n > 3)位数,第n位不能和前面n-1位相同,所有符合条件的n位数有9 x 9 x 8 x ... x (11-n)

显然,当n >= 11时,不存在n位的满足条件的数。


时间复杂度:O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值