【LeetCode 233】所有小於等於n的整數中,1出現的總次數,(例如111算3次)
阿新 • • 發佈:2019-01-08
聽說找工作的都推薦刷LeetCode,那我也搭配著做一些。
題目連結:
https://leetcode.com/problems/number-of-digit-one/
/*
題目:給一個n, 找出從1到<=n,裡所有整數的每一位上出現的1的總次數,例如n = 13, 則1,10,11,12,13,有6個1
思路:
暴力解法O(n), 當n到10^9會超時,故需要找規律
分析可得
0 - 9:1個
10 - 99:10 + 9 * 1
100 - 999:100 +9 * (10 + 9 * 1 + 1)
1000 - 9999:1000 + 9 * sum(2)
...
so:
1. 求出n的最高位,得到<=最高位-1位的sum
2. 加上當前最高位的,分為high==1, high>1,
3. 最高位得到的1的總個數 + 去掉最高位的總個數,迭代
*/
// 2016-5-5 20:17:32 // 2016-5-5 21:21:40 #include<stdio.h> #include<math.h> #include<iostream> using namespace std; _int64 a[10]; // 改成long long _int64 sum[10]; int init = 0; class Solution { public: int countDigitOne(int n) { int i, j; if (init == 0) { a[0] = 1; sum[0] = a[0]; for (i = 1; i <=9; i++) { a[i] = pow(10, i) + 9 * sum[i - 1]; sum[i] = sum[i - 1] + a[i]; } init = 1; /* for (i = 0; i<= 9; i++) { printf("%I64d ", a[i]); } printf("\n"); for (i = 0; i<= 9; i++) { printf("%I64d ", sum[i]); } printf("\n"); */ } if (n <= 0) return 0; int num[10]; int nBit = 0; int n2 = n; while (n2 != 0) { num[nBit++] = n2 % 10; n2 /= 10; } if (nBit == 1) { if (n >= 1) return 1; return 0; } int ans = 0; // ans += sum[nBit - 2]; int high = num[nBit - 1]; int low = n - high * pow(10, nBit - 1); if (high == 1) { ans += low + 1; } else { ans += pow(10, nBit - 1); ans += (high - 1) * sum[nBit - 2]; } ans += countDigitOne(low); return ans; } }; int main() { Solution s; cout<< s.countDigitOne(1234567890) << endl; return 0; }