[LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数
?
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])
Hint:
Credits:
Special thanks to @memoryless for adding this problem and creating all test cases.
?
這道題讓我們找一個范圍內(nèi)的各位上不相同的數(shù)字,比如123就是各位不相同的數(shù)字,而11,121,222就不是這樣的數(shù)字。那么我們根據(jù)提示中的最后一條可以知道,一位數(shù)的滿足要求的數(shù)字是10個(0到9),二位數(shù)的滿足題意的是81個,[10 - 99]這90個數(shù)字中去掉[11,22,33,44,55,66,77,88,99]這9個數(shù)字,還剩81個。通項公式為f(k) = 9 * 9 * 8 * ... (9 - k + 2),那么我們就可以根據(jù)n的大小,把[1, n]區(qū)間位數(shù)通過通項公式算出來累加起來即可,參見代碼如下:
?
解法一:
class Solution { public:int countNumbersWithUniqueDigits(int n) {if (n == 0) return 1;int res = 0;for (int i = 1; i <= n; ++i) {res += count(i);}return res;}int count(int k) {if (k < 1) return 0;if (k == 1) return 10;int res = 1;for (int i = 9; i >= (11 - k); --i) {res *= i;}return res * 9;} };?
下面這種方法是上面方法的精簡版,思路完全一樣:
?
解法二:
class Solution { public:int countNumbersWithUniqueDigits(int n) {if (n == 0) return 1;int res = 10, cnt = 9;for (int i = 2; i <= n; ++i) {cnt *= (11 - i);res += cnt;}return res;} };?
最后我們來看題目提示中所說的回溯的方法,我們需要一個變量used,其二進(jìn)制第i位為1表示數(shù)字i出現(xiàn)過,剛開始我們遍歷1到9,對于每個遍歷到的數(shù)字,現(xiàn)在used中標(biāo)記已經(jīng)出現(xiàn)過,然后在調(diào)用遞歸函數(shù)。在遞歸函數(shù)中,如果這個數(shù)字小于最大值,則結(jié)果res自增1,否則返回res。然后遍歷0到9,如果當(dāng)前數(shù)字沒有在used中出現(xiàn)過,此時在used中標(biāo)記,然后給當(dāng)前數(shù)字乘以10加上i,再繼續(xù)調(diào)用遞歸函數(shù),這樣我們可以遍歷到所有的情況,參見代碼如下:
?
解法三:
class Solution { public:int countNumbersWithUniqueDigits(int n) {int res = 1, max = pow(10, n), used = 0;for (int i = 1; i < 10; ++i) {used |= (1 << i);res += search(i, max, used);used &= ~(1 << i);}return res;}int search(int pre, int max, int used) {int res = 0;if (pre < max) ++res;else return res;for (int i = 0; i < 10; ++i) {if (!(used & (1 << i))) {used |= (1 << i);int cur = 10 * pre + i;res += search(cur, max, used);used &= ~(1 << i);}}return res;} };?
參考資料:
https://leetcode.com/discuss/107981/backtracking-solution
https://leetcode.com/discuss/108119/java-concise-dp-solution
?
LeetCode All in One 題目講解匯總(持續(xù)更新中...)
總結(jié)
以上是生活随笔為你收集整理的[LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到被人放狗咬是什么意思
- 下一篇: 全栈测试:平衡单元测试和端到端测试