[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 1on 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 };