日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数

發(fā)布時間:2023/11/29 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

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:

  • A direct way is to use the backtracking approach.
  • Backtracking should contains three states which are (the current number, number of steps to get that number and a bitmask which represent which number is marked as visited so far in the current number). Start with state (0,0,0) and count all valid number till we reach number of steps equals to 10n.
  • This problem can also be solved using a dynamic programming approach and some knowledge of combinatorics.
  • Let f(k) = count of numbers with unique digits with length equals k.
  • f(1) = 10, ..., f(k) = 9 * 9 * 8 * ... (9 - k + 2) [The first factor is 9 because a number cannot start with 0].
  • 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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。