233. Number of Digit One

weixin_33912445發表於2017-05-08

問題

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

例子

Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

分析

詳見頁碼統計

舉一個簡單的例子,求0-5137這5138個數字中出現1的個數,就等價於求1在個位、十位、百位、千位出現的個數的總和。現考慮1在百位出現的個數。簡單地列舉一下,有100-199,1100-1199,2100-2199,...,5100-5137總共500+37=537個;如果求0-5037出現1的個數,有100-199,1100-1199,2100-2199,...,4100-4199總共500個;如果求0-5237出現1的個數,有100-199,1100-1199,2100-2199,...,5100-5199總共600個。

可以得出結論,對應一個數AbC,b是一個0-9的數字,0-AdC中出現在b位置上的1的個數和b的大小有關:

  • b=0,個數為A*10^C的位數;
  • b=1,個數為A*10^C的位數 + C;
  • b>1,個數為(A+1)*10^C的位數。

知道了這個規律,依次求出每位上1的個數加起來就是總結果了。

要點

多寫寫畫畫找找規律。

時間複雜度

O(n),n是數字的位數

空間複雜度

O(1)

程式碼

class Solution {
public:
    int countDigitOne(int n) {
        if (n <= 0) return 0;
        long long cnt = 0;
        for (long long i = 1, j; j = n / i; i *= 10) {
            long long high = j / 10;
            long long low = n - j * i;
            long long digit = j % 10;
            
            cnt += high * i;
            if (digit > 1)
                cnt += i;
            else if (digit == 1)
                cnt += low + 1;
        }
        return cnt;
    }
};

相關文章