【劍指offer】43 1-n整數中1出現的次數(難)

面試題43. 1~n整數中1出現的次數

難度中等28

輸入一個整數 n ,求1~n這n個整數的十進制表示中1出現的次數。

例如,輸入12,1~12這些整數中包含1 的數字有1、10、11和12,1一共出現了5次。

 

示例 1:

輸入:n = 12
輸出:5

示例 2:

輸入:n = 13
輸出:6

解題思路:剛開始自己用的普通方法,結果時間超限了。

class Solution {
    public static int countOne(int n){
        int count = 0;
        StringBuilder sb = new StringBuilder();
        if(n>9){
            int temp = n%10;
            n = n/10;
            sb.append(temp);
        }
        sb.append(n);
        String s = String.valueOf(sb);
        for(int i = 0;i<s.length();i++){
            if(s.charAt(i) == '1')
                count++;
        }
        return count;
    }
    public int countDigitOne(int n) {
        int sum = 0;
        for(int i = 1;i<=n;i++){
            sum+=countOne(i);
        }
        return sum;
    }
}

思路是對的,就是方法太low,遇到比較大的數字就會時間超限。

解法二:

dfs(n)表示數字n有多少個1;

我們可以利用這樣的例子進行思考, 

假設數字爲1234,則high = 1 pow = 1000 low = 234;

其中當高位爲1的時候的1的個數 234+1(low+1);

然後就是pow中1的個數爲 dfs(pow)

low中1的個數爲 dfs(low)

最後結果就是low+1+dfs(pow)+dfs(low)

假設數字是2234 則high = 2,pow = 1000 low = 234

則可以將數字分成 0 - 999,1000-1999,2000-2234,

在0-999範圍內,dfs(pow-1)

在1000-1999範圍內分爲兩部分

當高位確定是1的時候:就是1的個數就是pow

拋開高位爲1的情況:就是dfs(pow-1)

2000-2234

就是dfs(low)

最後的結果就是

pow+high*dfs(pow-1)+dfs(low)

class Solution {
    public int dfs(int n){
        if(n<=0)
            return 0;
        String s = String.valueOf(n);
        int high = s.charAt(0) - '0';
        int pow = (int)Math.pow(10,s.length()-1);
        int low = n-high*pow;
        if(high == 1){
            return dfs(pow-1)+low+1+dfs(low);
        }else{
            return pow+high*dfs(pow-1)+dfs(low);
        }    
    }
    public int countDigitOne(int n) {
        return dfs(n);
    }
}

 

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