一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情。
力扣357. 统计各位数字都不同的数字个数
一、题目描述:
给你一个整数 n ,统计并返回各位数字都不同的数字 x 的个数,其中 0 <= x < 10^n 。
示例 1:
输入:n = 2 输出:91 解释:答案应为除去 11、22、33、44、55、66、77、88、99 外,在 0 ≤ x < 100 范围内的所有数字。 示例 2:
输入:n = 0 输出:1
提示:
0 <= n <= 8
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/co… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
-
这道题考察了什么思想?你的思路是什么?
这道题目我的第一想法是暴力枚举,但是很有可能会超时。
于是我继续观察这道题目,不重复?是不是没后一位就少一种可能!
于是我马上动手。
n为0时,x的个数为1,这个样例有提示,因为n大于1时,第一位不可能为0,所以我们n=1时,有10个。
-
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
题目没读懂,我以为就是求n位的所有数字,结果还要求小于n位的所有位数的数字之和。
后来仔细推导了样例才明白!!!!!
大家要注意!
-
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
我这种方法不是最优解,我看到了有大佬计算出递推公式,然后用递推法解决这道题目。
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
vector<int> dp(9, 0);
dp[0] = 1;
dp[1] = 10;
for(int i=2; i<=n; i++){
dp[i] = dp[i-1] + (dp[i-1]-dp[i-2])*(10-(i-1));
}
return dp[n];
}
};
作者:aijun
链接:https://leetcode-cn.com/problems/count-numbers-with-unique-digits/solution/by-aijun-9w89/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
其实我觉得最强的解法是这种!
class Solution:
def countNumbersWithUniqueDigits(self, n: int) -> int:
return [1, 10, 91, 739, 5275, 32491, 168571, 712891, 2345851][n]
哈哈哈哈哈哈哈哈哈,是不是很强的解法!
三、AC 代码:
int countNumbersWithUniqueDigits(int n){
if(n==0) return 1;
if(n==1) return 10;
int k=9,m=9;
int res = 10;
for(int i=1;i<n;i++){
k*=(m--);
res+=k;
}
return res;
}
四、总结:
数学思维在解决算法题时往往能起到事半功倍的作用,我们的数学功底要扎实!