LeetCode 357 统计各位数字都不同的数字个数[动态规划 排列组合] HERODING的LeetCode之路
Posted HERODING23
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 357 统计各位数字都不同的数字个数[动态规划 排列组合] HERODING的LeetCode之路相关的知识,希望对你有一定的参考价值。
解题思路:
首先最简单的方法一定是直接找出每个区间内的不同数字个数,因为n的取值只有8个,暴力点每个都算出来switch返回即可,代码如下:
class Solution
public:
int countNumbersWithUniqueDigits(int n)
switch (n)
case 0: return 1;
case 1: return 10;
case 2: return 91;
case 3: return 739;
case 4: return 5275;
case 5: return 32491;
case 6: return 168571;
case 7: return 712891;
case 8: return 2345851;
case 9: return 5611771;
default : return 8877691;
return 0;
;
第二种方法是动态规划的方法,说是动态规划,其实也就是每次10k-1——10k区间的位不同数字个数与之前区间的统计加起来,每个区间的数字个数又和排列组合相关,比如一个四位数,那么第一位能取9个数(除了0),第二位能取9个数(除了第一位),第三位取8个数,最后一位取7个数,相乘起来就是该区间的各位数不同的个数了,代码如下:
class Solution
public:
int countNumbersWithUniqueDigits(int n)
if(n == 0) return 1;
vector<int> dp(n + 1);
dp[0] = 1;
dp[1] = 10;
for(int i = 2; i <= n; i ++)
dp[i] = dp[i - 1] + (dp[i - 1] - dp[i - 2]) * (11 - i);
return dp[n];
;
第三种方法直接套用排列组合,在遍历的时候,一个变量存储当前总和,一个变量存储当前的排列组合规律(9*9*8*…*(n-1)),代码如下:
class Solution
public:
int countNumbersWithUniqueDigits(int n)
int res = 1;
int choose = 9;
for(int i = 1; i <= n; i ++)
res += choose;
choose = choose * (10 - i);
return res;
;
最后一种方法可能大家也猜到了,就是递归的思路,这样短短三行代码就能实现,代码的思路本质上和排列组合相同,代码如下:
class Solution
public:
int countNumbersWithUniqueDigits(int n)
if(n == 0) return 1;
if(n == 1) return 10;
return countNumbersWithUniqueDigits(n - 1) + (countNumbersWithUniqueDigits(n - 1) - countNumbersWithUniqueDigits(n - 2)) * (11 - n);
;
以上是关于LeetCode 357 统计各位数字都不同的数字个数[动态规划 排列组合] HERODING的LeetCode之路的主要内容,如果未能解决你的问题,请参考以下文章
[Leetcode] 第357题 计算各个位数不同的数字个数
357 Count Numbers with Unique Digits 计算各个位数不同的数字个数
LeetCode 2180. 统计各位数字之和为偶数的整数个数