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

 

你可能感兴趣的:(LeetCode)