/**
* 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.
*
* Tags: Math
* Similar Problems: (E) Factorial Trailing Zeroes
*/
public class NumberOfDigitOne {
/**
* e.g n = 3141592, m = 100, a = 31415, b = 92
* hundreds-digit of n is 1 for 3142 times, each has a 100 long streak, (a / 10 * 100) + 100
* when m = 1000, a = 3141, b = 592
* thousands-digit of n is 1 for 315 times, each has a 1000 long streak
* since the digit is 1, the very last streak isn't 100 but only 592 + 1 = 593 numbers, (a / 10 * 1000) + (b + 1)
* so the case is different when current digit is 0 or 1 or >= 2
* (a + 8) / 10 is the number of full streaks (if current digit is 0 or 1, there won't be a full streak)
* a % 10 == 1 tells whether to add a partial streak (add partial streak only if current digit is 1)
*/
public int countDigitOne(int n) {
int res = 0;
for (long m = 1; m <= n; m *= 10)
res += (n / m + 8) / 10 * m + (n / m % 10 == 1 ? n % m + 1 : 0);
return res;
}
}