根据题目描述可知,此题要求的1是由[1,n]之间所有数的位数为1的个数
测试用例:10,112,226
112
个位:[1][11,21,...,111]
1 + 11*1
十位:[10,11,...,19][110,...,112]
10 + 3
百位:[100,...,112][]
13
226
[1][11,21,...,221]
1 + 22*1
[10,11,...,19][110,...119,210,...219]
10 + 2*10
[100,...,199][]
100
10
[1][]
1
[10][]
1
根据以上例子,得到规律,代码实现如下:
private static int solution2(int n) { int count = 0; for (int i = 1; i <= n; i *= 10) { // 位前半部分计算 int bitLess = n / i > 1 ? i : (n % i + 1); // 位后半部分计算 int bitMore = 0; if (n / (i * 10) > 0) { if (n % (i * 10) >= (2 * i - 1)) { bitMore = n / (i * 10) * i; } else { bitMore = (n / (i * 10) - 1) * i; if (n % (i * 10) > 0) bitMore += n % i + 1; } } count += bitLess + bitMore; } return count; }
小结:
该解法的时间复杂度为O(logN),这里的对数是10为底
较之寻常解法的时间复杂度,优化了不少