[LeetCode] Number of Digit One
The following idea is taken from a book named 《剑指offer》 published in China.
Suppose n = 271
, it then breaks [1, 271]
into [1, 71]
and [72, 271]
. For [72, 271]
, the number of 1
on the hundreds are 10^2 = 100
(note that if the digit on the higest bit is 1
, then the number of 1
's on that bit will be 72
, which is 271 % 100 + 1
). To compute the number of 1
on tens and units, we further break [72, 271]
into [72, 171]
and [172, 271]
. Each interval has 10^1 = 10
1
's on both the tens and units. So the overall number of 1
's on tens and units is2 * 2 * 10^1 = 40
. Now we are only left with [1, 71]
, which can be solved recursively. Theint n
is transformed into a string num
to facilitate some operations.
The code is as follows.
1 class Solution { 2 public: 3 int countDigitOne(int n) { 4 if (n <= 0) return 0; 5 string num = to_string(n); 6 return countOne(num); 7 } 8 private: 9 int countOne(string num) { 10 if (num.empty()) return 0; 11 int first = num[0] - '0'; 12 if (num.length() == 1) { 13 if (first) return 1; 14 return 0; 15 } 16 int highestBit; 17 if (first > 1) highestBit = powerTen(num.length() - 1); 18 else if (first == 1) highestBit = stoi(num.substr(1)) + 1; 19 int otherBits = first * (num.length() - 1) * powerTen(num.length() - 2); 20 int recurCount = countOne(num.substr(1)); 21 return highestBit + otherBits + recurCount; 22 } 23 int powerTen(int exp) { 24 int p = 1; 25 for (int i = 0; i < exp; i++) 26 p *= 10; 27 return p; 28 } 29 };
This link has a brilliant 4-line solution! The code is rewritten as follows.
1 class Solution { 2 public: 3 int countDigitOne(int n) { 4 int counts = 0; 5 for (int m = 1000000000; m; m /= 10) 6 counts += (n / m + 8) / 10 * m + (n / m % 10 == 1) * (n % m + 1); 7 return counts; 8 } 9 };