輸入乙個整數 n ,求1~n這n個整數的十進位制表示中1出現的次數。
例如,輸入12,1~12這些整數中包含1 的數字有1、10、11和12,1一共出現了5次。
示例:
輸入:n = 12本題在求解時有點動態規劃的思想,即利用小規模的問題去迭代求解大規模的問題,我們首先來看:輸出:5
1、0-9
中1的個數是1
;
2、0-99
中1的個數是9*1+10+1 = 20
對於0-99
來說,我們可以將其拆0-89
+90-99
,對於0-89
,可分開求十位上的1和和非十位上的1的情況,非十位上的1(1,11,21,…,81)的情況9*1
種,十位上的1(10,11,…,19)情況有10
種;對於90-99
(其實就是我們求得0-9的情況)只有1
種,故加起來就是9*1+10+1
。
3、0-999
中1的個數是9*20+100+20 = 300
同樣的,對於0-999
來說,我們在上述的基礎上進行拆分,可以分為0-899
+900-999
,對於0-899
的情況,可分開求百位上的1和非百位上的1的情況,非百位上的1就是9*20
種,百位上的1就是100
種。對於900-999
(其實就是我們求得0-99的情況)有20
種。故加起來就是9*20+100+20
從上述案例來說,即是先算個位有1的情況,然後利用低位依次去計算高位。
例如:321,求1的個數?
對於個位1來說,1的個數是1
;
對於十位21來說,1的個數是2*1+10+1=13
;
對於百位321來說,1的個數是3*20+100+13=173
;
——3 * 20 表示的是,0 - 99 、100 - 199、200 - 299中,三段0-99的1總和
——100 表示對於最高位為1的情況,也就是100-199,最高位有100個1
——13 表示300-321中,00-21的1總和,其實就是上一次的運算結果
需要注意的是,如果行號高位為1的話,例如121,此時高位就沒有100-199,只有100-121,那麼1的個數就是22,此時就是1*20+22+13
;
由此可推得公式:res = num*f[flag] + ~~10^falg~~ + res;
劃線部分需要在是否等於1時進行判斷。
針對題目中數字最大為2^31次方,最多只有10位數。所以綜上所述我們可以列出f(n)即,0-9;0-99;0-999;…
此外需要將f(0) = 0;以滿足公式的通用性。
f(1) = 1;
f(2) = 20;
f(3) = 300;
f(4) = 4000;
f(5) = 50000;
f(6) = 600000;
f(7) = 7000000;
f(8) = 80000000;
f(9) = 900000000;
f(10) = 10,000,000,000;
int
countdigitone
(int n)
;int count =0;
int res =0;
long flag =1;
int tmp = n;
while
(tmp !=0)
return res;
}
你明白了嗎,臭豬?@要努力的魚~嘿嘿 1 n整數中1出現的次數
示例 1 輸入 n 12 輸出 5 示例 2 輸入 n 13 輸出 62.1 思路分析 題目要求1 n中1出現的次數,考慮將n轉換為字串,然後統計字元1的個數,但這樣會超時 既然1不行,換一種思路,將n轉換為字串後,可以容易確定n的位數 利用for迴圈,從個位開始直到最高位,計算每一位上1出現的次數...
1 n 整數中1出現的次數(21)
方法一 將每個數字中的1的個數進行相加,最終的結果就是1出現的總的次數。但是這種方法的效率較低,時間複雜度為 o n log n o n log n o n lo gn 當n非常大的時候,需要大量的計算。class solution return sumofone int numofone int ...
求1 n整數中1出現的次數
自己不會,看看大神的解法,自己總結一下下,有更好的思路,望指教!解題思路 將數字進行拆分,分為三部分,高位,低位,和當前位 以求十位出現1的次數為例,digit 10 1.以n 1202為例,此時,高位high 12,低位low 2,當前位cur 0 此時十位出現1 的數字的範圍是 0010 111...