357. Count Numbers with Unique Digits

Total Accepted: 450 Total Submissions: 1077 Difficulty: Medium

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:

  1. A direct way is to use the backtracking approach.
  2. Backtracking should contains three states which are (the current number, 
  3. number of steps to get that number and a bitmask which represent which number is marked as visited so far in the current number). 
  4. Start with state (0,0,0) and count all valid number till we reach number of steps equals to 10n.
  5. This problem can also be solved using a dynamic programming approach and some knowledge of combinatorics.
  6. Let f(k) = count of numbers with unique digits with length equals k.
  7. 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.

Subscribe to see which companies asked this question

Show Tags

分析與翻譯:

給定一個非負整數 n,計算所有各位數字均不同的數字x的個數,其中0 ≤ x < 10^n。
例子:

給定n=2,答案爲91.因爲在0-100的數字中除了11,22,33,44,55,66,77,88,99其他所有數各位均不同。
提示:
1)一個直接的辦法是使用回溯法。
2)回溯應當包含三個狀態(當前數字,得到該數字需要的步數,以及一個比特掩碼用來表示當前已經訪問過哪些位)。從狀態(0,0,0)開始,並計算直到10^n爲止的有效數字個數。
3)這個問題也可以使用動態規劃方法與一些組合的知識來求解。
4)定義子問題f(k) :長度爲k時各位均不同數字的個數。
5)f(1) = 10, ..., f(k) = 9 * 9 * 8 * ... (9 - k + 2) [首個因數是9,因爲數字不能從0開始].

分析開始:找規律

既然說可以用動態規劃,並且子問題都給你定義好了,那麼這個問題就簡單了!

n=1時,一位數A,[0,10)顯然10個,
n=2時,兩位數AB,[0,100),第一位A有9種選擇(不能爲0),第二位B有9中選擇,81種,再加一位的10種,共91種
n=3時,三位數ABC,[0,1000),同理,A有9種可能,B有9種,C有8種...9*9*8+81+10=739

...

所以f(k) = 9 * 9 * 8 * ... (9 - k + 2),我們所做工作只是累加f(1)到f(n)即可,分析完畢。

代碼一目瞭然,不言而喻

class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        int result=0;
        for(int i=1;i<=n;i++)
            result+=getfk(i);
        return result==0?1:result;
    }
    
    int getfk(int k)
    {
        if(k==1)
            return 10;
        int val=9;    
        for(int i=2;i<=k;i++)
            val*=(9-i+2);
        return val;
    }
};

簡寫代碼:

class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        if ( n < 0 )  
            return 0;
        int result = 1;
        int multiplier = 9;
        n = min(n, 10);
        for (int i = 1; i <= n; i++) {
            result += multiplier;
            multiplier *= (i > 9 ? 0: (10 - i));
        }
        return result;
    }
};





注:本博文爲EbowTang原創,後續可能繼續更新本文。如果轉載,請務必複製本條信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/51658886

原作者博客:http://blog.csdn.net/ebowtang

本博客LeetCode題解索引:http://blog.csdn.net/ebowtang/article/details/50668895

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