1. 程式人生 > >統計1到N之間所有數字中1的個數

統計1到N之間所有數字中1的個數

本文中的code和思想來自於https://leetcode.com/discuss/44281/4-lines-o-log-n-c-java-python ,感謝作者

code如下:

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

m為從1開始到N之間的所有的10的倍數值。比如1 , 10 ,100 ... 

通過m可以將n劃分成為兩個部分,比如數字3141592 , 那麼當m = 100的時候,劃分的結果是31415 和 92 ,那麼百位的字首就是從“ ”到“3141” ,這個看成是3142條的資料,因為這個是百位的字首。那麼百位是1的元素就有,(a/10 + 1)*100個

然後來看看千位,同時千位就是m = 1000 的時候,這個時候可以將數字劃分為 a = 3141 和 b = 592 ,千位的字首就是 從“ ” 到“314” ,一共有315次,然而, 因為千位是1,最後一條只有593 條的資料,也就是 從”000“到”592“ ,所以要分開算。那麼加起來,這個情況一共有( a/10 *1000 ) + (b +1  )  次

然後比較魔幻的是,上面兩種情況

當a/10 最後一為是 0 ,或者是1 的話,那麼最後一位加上 8 後除以10,那麼還是0 ,但是如果是大於等於2,那麼 就是1了

如果最後一位是1的時候,需要加上b+1 , 如果不是1的話,就不需要,所以上面的公式可以整理成為

((a + 8 )/10 )* m + (a %10 == 1)  * (b +1 )