數(shù)數(shù)字的題目說難也難籽腕,說簡單也簡單,難就難在不重不漏纸俭,簡單就簡單在方法找對了皇耗,就是一個(gè)公式的事兒。
這道題的思路其實(shí)不難找揍很,我們考慮一下什么時(shí)候會(huì)出現(xiàn)數(shù)字1:
1郎楼、11、21窒悔、……呜袁、91
10、11简珠、12阶界、……、19
100聋庵、101膘融、……、199
我們看到祭玉,統(tǒng)計(jì)1在各個(gè)數(shù)位上出現(xiàn)的次數(shù)比較簡單氧映,不會(huì)重復(fù)也不易遺漏。我們看到11在這里出現(xiàn)了兩次脱货,按照數(shù)位計(jì)算的話就是十位計(jì)算一次個(gè)位計(jì)算一次岛都,并不會(huì)產(chǎn)生重復(fù)。
現(xiàn)在的問題就是蹭劈,如何計(jì)算各個(gè)數(shù)位上1的個(gè)數(shù)疗绣。
比如我們看數(shù)字,個(gè)位上有多少個(gè)
呢铺韧?把
分成
和
兩部分多矮,可以看到,前一部分可以取
,后一部分可以取
塔逃,于是個(gè)位上
的個(gè)數(shù)就是
讯壶。
下面我們看十位,同樣的思路湾盗,我們把分成
和
兩部分伏蚊,前一部分可以取
,后一部分可以取
于是十位上是
的個(gè)數(shù)為
格粪。
依次進(jìn)行下去并將結(jié)果相加即為最終結(jié)果躏吊。
需要注意的特殊情況是某一位上的數(shù)字為和
的情況,比如
帐萎,我們在考查十位上數(shù)字
的個(gè)數(shù)的時(shí)候應(yīng)該取
(而非
)
比伏,因?yàn)?img class="math-inline" src="https://math.jianshu.com/math?formula=07%3C10" alt="07<10" mathimg="1">。
當(dāng)數(shù)字為疆导,十位上數(shù)字
的個(gè)數(shù)為
赁项。
從而我們可以由以上規(guī)律得到一個(gè)統(tǒng)一的計(jì)算公式,代碼如下:
class Solution {
public:
int countDigitOne(int n)
{
int res = 0;
for (long i=1;i<=n;i*=10)
res+=(n/i+8)/10*i+(n/i%10==1)*(n%i+1);
return res;
}
};