1279. 計算不同數字整數的個數

從物理學到計算機,再到硬件,再到人工智能!
藍橋杯備賽 (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]);
		}
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章