問題:
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n.
Example:
Given n = 2, return 91. (The answer should be the total numbers in the range of 0 ≤ x < 100, excluding [11,22,33,44,55,66,77,88,99])
大意:
給出一個(gè)非負(fù)整數(shù)n颈走,計(jì)算所有單獨(dú)數(shù)字組成的數(shù) x 的數(shù)量院峡,0 ≤ x < 10的n次方。
例子:
給出 n = 2桌硫,返回 91动壤。(答案應(yīng)該包含0 ≤ x < 100范圍內(nèi)的所有數(shù)萝喘,除了[11,22,33,44,55,66,77,88,99])
思路:
這道題的意思是,對于0到10的n次方內(nèi)的數(shù)琼懊,計(jì)算其中所有數(shù)都唯一的數(shù)的數(shù)量阁簸,比如19每一位都是唯一的數(shù)字,而11有兩個(gè)1重復(fù)了哼丈,是這個(gè)意思启妹,所以當(dāng)給出n為2時(shí),是計(jì)算0到99內(nèi)的唯一組成數(shù)的數(shù)量醉旦,只有11饶米、22...這些重復(fù)的數(shù)的組成不唯一,共9個(gè)车胡,所以100-9=91檬输。
我們需要找一下規(guī)律:
當(dāng) n = 0 時(shí),0這個(gè)數(shù)是唯一組成的匈棘。
當(dāng) n = 1 時(shí)丧慈,10個(gè)數(shù)都是唯一組成的。
當(dāng) n = 2 時(shí)主卫,除了頭10個(gè)數(shù)外逃默,每個(gè)十位上的數(shù)只會(huì)有一個(gè)個(gè)位上的數(shù)重復(fù)的情況,共有1~9簇搅,9個(gè)十位上的數(shù)完域,每個(gè)對應(yīng)有9個(gè)數(shù)是唯一組成的,所以是 99瘩将。
當(dāng) n = 3 時(shí)吟税,出了頭100個(gè)數(shù)的結(jié)果不影響外,對于三位數(shù)姿现,還要排除百位數(shù)和其余位的數(shù)重復(fù)的情況肠仪,也就是說原來的99,變成了98建钥,所以9個(gè)百位數(shù)共有 998 這些數(shù)藤韵。
當(dāng) n = 4 時(shí)虐沥,除了頭1000個(gè)數(shù)熊经,還有 9987這些數(shù)泽艘。
。镐依。匹涮。
當(dāng) n = 10 時(shí),除了前面的數(shù)槐壳,還有 998765432*1 個(gè)數(shù)然低。
當(dāng) n >= 11 時(shí),除了前面的數(shù)务唐,到后面的數(shù)因?yàn)槲粩?shù)超過10了雳攘,已經(jīng)不可能不重復(fù)了,所以不再有新的唯一組成數(shù)出現(xiàn)了枫笛。
注意以上計(jì)算數(shù)量時(shí)都要加上前面出現(xiàn)的數(shù)吨灭,是個(gè)累加的過程。
代碼(Java):
public class Solution {
public int countNumbersWithUniqueDigits(int n) {
if (n == 0) return 1;
int result = 10;
int middle = 9;
int decrease = 9;
while (n > 1 && decrease > 0) {
middle = middle * decrease;
result += middle;
decrease --;
n--;
}
return result;
}
}
合集:https://github.com/Cloudox/LeetCode-Record