一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。
个人博客链接:bbstudy.net/ (等毕业论文做好后续会完善相关功能)
4.11:统计各位数字都不同的数字个数
LeetCode 357,点击题目可直接跳转至LeetCode
题解一:暴力DFS
n最大为8,比较容易想到的思路便是直接通过dfs遍历每一位数字,如果各位数字都不同则记录数+1,最终统计满足条件的个数即可。
注意:前导0的情况需要特判下。
缺点:费时
C++代码:
class Solution {
public:
map<int,int> mp;
int ans;
int check(){
for(int i=1;i<10;i++) if(mp[i]) return 0;
return 1;
}
void dfs(int cnt,int n){
if(cnt>n){
++ans;return ;
}
for(int i=0;i<10;i++){
if(mp[i]) continue;
if(check()&&i==0){ //前面全是前导0
dfs(cnt+1,n);
}else{
mp[i]++;
dfs(cnt+1,n);
mp[i]--;
}
}
}
int countNumbersWithUniqueDigits(int n) {
mp.clear();
if(n==1) return 10;
ans=0;
dfs(1,n);
return ans;
}
};
题解二:排列组合
官方提供的思路。
- n=0时:,满足条件个数为:1个
- n=1时:,满足条件个数为:0~9,10个
-
n=2时:,可以由两部分构成:只有一位数的情况和两位数的情况。其中
- 只有一位数的情况由上述可得x有10种;
- 有两位数的情况:第一位可以取1-9(9种), 第二位可以取0-9除了和第一位不同的数字(9种),于是就有:9*9=81种。
-
n=3时,可以分为三部分:一位数、两位数、三位数
- 一位数:10种(0~9)
- 两位数:9*9=81种
- 三位数:998
-
扩展至n>=2:含有n位数字的情况,可以表示为:9*
于是代码如下:
C++代码:
class Solution {
public:
int countNumbersWithUniqueDigits(int n) {
if(n==0) return 1;
else if(n==1) return 10;
int ans=10,num=9;
for(int i=1;i<=n-1;i++){
num*=(9-i+1); //9*9*8*....
ans+=num;
}
return ans;
}
};
当然,还有其他的解法,比如:n最大为8,可以直接打表(存储n为0~8的结果);还可以用dp等等,此处并不一一列举。