從物理學到計算機,再到硬件,再到人工智能!
藍橋杯備賽 (LintCode上刷的第十一題)
問題描述
給定非負整數n,計算具有不同數字字符的所有整數,其中0≤x<10 ^ n。
樣例輸出
給定n =2,返回91。
答案應該是0≤x<100範圍內的總數,除去[11,22,33,44,55,66,77,88,99]
問題分析
所有的思想都在代碼裏面啦!
JAVA代碼實現
package DP;
public class CountNumbersWithUniqueDigits1279_1115 {
/**
* 計算具有不同數字字符的所有整數,其中0≤x<10 ^ n
* dp(1) = 10 dp(2) = 9 × 9 + dp(1)
* dp(3) = 9 × 9 ×8 + dp(2)
* dp[i] = 9 × [9 × 8 × 7 × ... × (9 - i + 2)] + dp(i - 1)
* @param n 非負整數,
* @return
*/
public static int[] countNumbersWithUniqueDigits(int n) {
// 創建一個數組dp,dp[i]表示i位數時具有不同數字的所有整數的個數
int[] dp = new int[n + 1];
// 一共有10個一位數
int k = 10;
// 一位數中具有不同數字的所有整數的個數
dp[1] = k;
// 遍歷所有小於位數n的情況
for (int i = 2; i < n + 1; i++) {
// 中間部分的連續整數的乘積採用組合的方式求解
dp[i] = (int) ((k - 1) * combination(i - 1, k - 1) + dp[i - 1]);
}
return dp;
}
/**
* 計算階乘數,即n! = n * (n-1) * ... * 2 * 1
*
* @param n
* @return
*/
private static long factorial(int n) {
long sum = 1;
while (n > 0) {
sum = sum * n--;
}
return sum;
}
/**
* 組合計算公式C<sup>m</sup><sub>n</sub> = n! / (m! * (n - m)!)
*
* @param m
* @param n
* @return
*/
public static long combination(int m, int n) {
return m <= n ? factorial(n) / (factorial(m) * factorial((n - m))) : 0;
}
public static void main(String[] args) {
int n = 3;
int[] res = countNumbersWithUniqueDigits(n);
for (int i = 1; i <= n; i++) {
System.out.println(res[i]);
}
}
}