[LeetCode] Number of Digit One 數字1的個數
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.
Hint:
- Beware of overflow.
這道題讓我們比給定數小的所有數中1出現的個數,之前有道類似的題
1的個數 含1的數字 數字範圍
1 1 [1, 9]
11 10 11 12 13 14 15 16 17 18 19 [10, 19]
1 21 [20, 29]
1 31 [30, 39]
1 41 [40, 49]
1 51 [50, 59]
1 61 [60, 69]
1 71 [70, 79]
1 81 [80, 89]
1 91 [90, 99]
11 100 101 102 103 104 105 106 107 108 109 [100, 109]
21 110 111 112 113 114 115 116 117 118 119 [110, 119]
11 120 121 122 123 124 125 126 127 128 129 [120, 129]
... ... ...
通過上面的列舉我們可以發現,100以內的數字,除了10-19之間有11個‘1’之外,其餘都只有1個。如果我們不考慮[10, 19]區間上那多出來的10個‘1’的話,那麼我們在對任意一個兩位數,十位數上的數字(加1)就代表1出現的個數,這時候我們再把多出的10個加上即可。比如56就有(5+1)+10=16個。如何知道是否要加上多出的10個呢,我們就要看十位上的數字是否大於等於2,是的話就要加上多餘的10個'1'。那麼我們就可以用(x+8)/10來判斷一個數是否大於等於2。對於三位數區間 [100, 199] 內的數也是一樣,除了[110, 119]之間多出的10個數之外,共21個‘1’,其餘的每10個數的區間都只有11個‘1’,所以 [100, 199] 內共有21 + 11 * 9 = 120個‘1’。那麼現在想想[0, 999]區間內‘1’的個數怎麼求?根據前面的結果,[0, 99] 內共有20個,[100, 199] 內共有120個,而其他每100個數內‘1’的個數也應該符合之前的規律,即也是20個,那麼總共就有 120 + 20 * 9 = 300 個‘1’。那麼還是可以用相同的方法來判斷並累加1的個數,參見程式碼如下:
解法一:
class Solution { public: int countDigitOne(int n) { int res = 0, a = 1, b = 1; while (n > 0) { res += (n + 8) / 10 * a + (n % 10 == 1) * b; b += n % 10 * a; a *= 10; n /= 10; } return res; } };
解法二:
class Solution { public: int countDigitOne(int n) { int res = 0; for (long k = 1; k <= n; k *= 10) { long r = n / k, m = n % k; res += (r + 8) / 10 * k + (r % 10 == 1 ? m + 1 : 0); } return res; } };
類似題目:
參考資料: