233 - Number of Digit One

Number of Digit One

 Total Accepted: 307 Total Submissions: 1853

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

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


兩經波折,一開始沒想過會有大數的效率問題,後來發現,哦,原來考察的是找規律。

一開始的超時,最簡單的解法:

        int countDigitOne(int n) {
                int sum = 0;
                for(int i = 1; i <= n; i++)
                        sum += count(i);
                return sum;
        }

        int count(int num) {
                int c = 0;
                while( num != 0 ) {
                        if(num % 10 == 1)
                                c++;
                        num = num / 10;
                }
                return c;
        }


超時後,參照了其他人的解法,努力去理解公式:

 ones += (a + 8) / 10 * m + (a % 10 == 1) * (b + 1);
發現,我的思路不對,肯定不能遍歷所有比 n 小的數字啊,這樣太慢了,因爲是有規律可循的。

但是理解上述公式還是很困難的,我現在能夠理解了,是經過自己拿數字去對應公式,比如3456這個數,利用這個公式去推導每一位可能爲1的所有比該數小的數字個數的總和。

慢慢的理解,就積累了一道這樣找規律的題目。另外,注意 a 和 b 要爲 long型(這是細節)。

        int countDigitOne(int n) {
                int ones = 0;
                for(long m = 1; m <= n; m *= 10) {
                        long a = n / m;
                        long b = n % m;
                        ones += (a + 8) / 10 * m + (a % 10 == 1) * (b + 1);
                }
                return ones;
        }


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