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 == ) return ;
int res = ;
for (int i = ; i <= n; ++i) {
res += count(i);
}
return res;
}
int count(int k) {
if (k < ) return ;
if (k == ) return ;
int res = ;
for (int i = ; i >= ( - k); --i) {
res *= i;
}
return res * ;
}
};

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

解法二:

class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if (n == ) return ;
int res = , cnt = ;
for (int i = ; i <= n; ++i) {
cnt *= ( - 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 = , max = pow(, n), used = ;
for (int i = ; i < ; ++i) {
used |= ( << i);
res += search(i, max, used);
used &= ~( << i);
}
return res;
}
int search(int pre, int max, int used) {
int res = ;
if (pre < max) ++res;
else return res;
for (int i = ; i < ; ++i) {
if (!(used & ( << i))) {
used |= ( << i);
int cur = * pre + i;
res += search(cur, max, used);
used &= ~( << i);
}
}
return res;
}
};

参考资料:

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

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

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

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

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

    给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n.示例:给定 n = 2,返回 91.(答案应该是除[11,22,33,44,55,66,77,88,99 ...

  2. Leetcode: Count Numbers with Unique Digits

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

  3. LC 357. Count Numbers with Unique Digits

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

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

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

  5. 【LeetCode】357. Count Numbers with Unique Digits 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  6. 【Leetcode】357. Count Numbers with Unique Digits

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

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

  8. Count Numbers with Unique Digits -- LeetCode

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

  9. Count Numbers with Unique Digits

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

随机推荐

  1. 读书笔记--SQL必知必会13--创建高级联结

    13.1 使用表别名 SQL可以对列名.计算字段和表名起别名. 缩短SQL语句 允许在一条SELECT语句中多次使用相同的表. 注意:表别名只在查询执行中使用,不返回到客户端. MariaDB [sq ...

  2. 现代3D图形编程学习-基础简介(1) (译)

    本书系列 现代3D图形编程学习 基础简介 并不像本书的其他章节,这章内容没有相关的源代码或是项目.本章,我们将讨论向量,图形渲染理论,以及OpenGL. 向量 在阅读这本书的时候,你需要熟悉代数和几何 ...

  3. 1.C#WinForm基础制作简单计算器

    利用c#语言编写简单计算器: 核心知识点: MessageBox.Show(Convert.ToString(comboBox1.SelectedIndex));//下拉序号 MessageBox.S ...

  4. Moon.Orm 入门总指南

    注意:下面的pdf文件强烈建议下载或在线查看 1)旗舰版帮助文档点击查看或下载 2)http://pan.baidu.com/s/1hq7krFu(新手手册下载)(强烈推荐) 3)性能及规范下载,网友 ...

  5. Redis简单案例(一) 网站搜索的热搜词

    对于一个网站来说,无论是商城网站还是门户网站,搜索框都是有一个比较重要的地位,它的存在可以说是 为了让用户更快.更方便的去找到自己想要的东西.对于经常逛这个网站的用户,当然也会想知道在这里比较“火” ...

  6. asp.net mvc View视图相关

    1.0 @helper语法 @helper语法可以定义可重复使用的帮助器方法: 例如 @helper methodName(type paramName,...){ //todo } 调用:@meth ...

  7. sql server left 和right 函数

    参考文章:微信公众号文章 一直对sql中的left和right有误解,一直以为它是这样的. 执行这样一句: ) leftNum ) rightNum 出现的结果是这样的: 而我心中这样认为: 我认为只 ...

  8. 配置IIS的通配符应用程序映射

    使用IIS 6架设网站,如果要使用伪静态的功能,可能需要设置“通配符应用程序映射(执行顺序)”. 在Windows Server 2012 r2 的IIS 8中,对应的是添加设置“通配符脚本映射”,参 ...

  9. .NET Core 1.1 发布 文档下载资源汇总

    .NET Core 1.1 RTM 版2016/11/16 发布.对应发布 ASP.NET Core 1.1 .EF Core 1.1. 你可以通过Visual Studio 2015, Visual ...

  10. bzoj2820--莫比乌斯反演

    题目大意: 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对. 推导: 设n<=m ans=  = 由于gcd(i,j)= ...