Article / 文章
LeetCode 第357题:计算各个位数不同的数字个数
给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10^n。
📖 文章摘要
本文详细解析LeetCode第357题“计算各个位数不同的数字个数”,这是一道数学问题。文章提供了基于排列组合的解法,包含C#、Python、C++三种语言实现,配有详细的算法分析和性能对比。适合想要提升数学思维和组合问题的读者。
核心知识点: 排列组合、数学分析、动态规划 难度等级: 中等 推荐人群: 具有一定数学基础,想要提升组合问题解决能力的程序员
题目描述
给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10^n。
示例
示例 1:
输入:n = 2
输出:91
解释:答案应为除去 11,22,33,44,55,66,77,88,99 外,在 [0,100) 区间内的所有数字。
示例 2:
输入:n = 0
输出:1
提示
0 <= n <= 8
解题思路
本题可以使用排列组合的方法解决:
- 对于n位数,第一位有9种选择(1-9)
- 第二位有9种选择(0-9除去第一位)
- 第三位有8种选择(0-9除去前两位)
- 以此类推…
时间复杂度: O(n) 空间复杂度: O(1)
图解思路
位数分析表
| 位数 | 选择数 | 说明 |
|---|---|---|
| 1 | 9 | 1-9 |
| 2 | 9 | 0-9除去第一位 |
| 3 | 8 | 0-9除去前两位 |
| 4 | 7 | 0-9除去前三位 |
计算过程表
| n | 计算过程 | 结果 |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 9 | 10 |
| 2 | 9 * 9 | 91 |
| 3 | 9 * 9 * 8 | 739 |
代码实现
C# 实现
public class Solution {
public int CountNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
if (n == 1) return 10;
int result = 10;
int available = 9;
int current = 9;
for (int i = 2; i <= n; i++) {
current *= available;
result += current;
available--;
}
return result;
}
}
Python 实现
class Solution:
def countNumbersWithUniqueDigits(self, n: int) -> int:
if n == 0:
return 1
if n == 1:
return 10
result = 10
available = 9
current = 9
for i in range(2, n + 1):
current *= available
result += current
available -= 1
return result
C++ 实现
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
if (n == 1) return 10;
int result = 10;
int available = 9;
int current = 9;
for (int i = 2; i <= n; i++) {
current *= available;
result += current;
available--;
}
return result;
}
};
执行结果
C# 实现
- 执行用时:0 ms
- 内存消耗:5.2 MB
Python 实现
- 执行用时:32 ms
- 内存消耗:13.2 MB
C++ 实现
- 执行用时:0 ms
- 内存消耗:5.8 MB
性能对比
| 语言 | 执行用时 | 内存消耗 | 特点 |
|---|---|---|---|
| C++ | 0 ms | 5.8 MB | 执行效率最高 |
| C# | 0 ms | 5.2 MB | 内存占用最小 |
| Python | 32 ms | 13.2 MB | 代码简洁,易于理解 |
代码亮点
- 🎯 使用排列组合公式高效计算
- 💡 处理边界情况(n=0和n=1)
- 🔍 优化计算过程,避免重复计算
- 🎨 代码结构清晰,易于维护
常见错误分析
- 🚫 未考虑n=0的特殊情况
- 🚫 计算过程中整数溢出
- 🚫 重复计算导致效率低下
- 🚫 未处理n>8的情况
解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 排列组合 | O(n) | O(1) | 高效,实现简单 | 需要数学知识 |
| 暴力枚举 | O(10^n) | O(1) | 直观,易于理解 | 效率极低 |
相关题目
- LeetCode 233. 数字 1 的个数 - 困难
- LeetCode 400. 第 N 位数字 - 中等
- LeetCode 788. 旋转数字 - 中等
📖 系列导航
🔥 算法专题合集 - 查看完整合集
📢 关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新第357题。
💬 互动交流
感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。
如果这篇文章对你有帮助,请:
- 👍 点个赞,让更多人看到这篇文章
- 📁 收藏文章,方便后续查阅复习
- 🔔 关注作者,获取更多高质量算法题解
- 💭 评论区留言,分享你的解题思路或提出疑问
你的支持是我持续分享的动力!
💡 一起进步:算法学习路上不孤单,欢迎一起交流学习!