這題,我只能看懂最基礎的,乙個個數,或者轉化成字串數1,找規律算的高效方法看了幾種解釋都是在不懂,附在下,但願之後能懂吧。。。
public
intnumberof1between1andn_solution
(int n)
return cnt;
}
解釋1
思路是分別計算個位、十位、百位…上出現 1 的個數。
以 n =216為例:
個位上: 1 ,11,21,31,…211。個位上共出現(216/10)+ 1個 1 。因為除法取整,210~216間個位上的1取不到,所以我們加8進製。你可能說為什麼不加9,n=211怎麼辦,這裡把最後取到的個位數為1的單獨考慮,先往下看。
十位上:1019,110119,210~216. 十位上可看成 求(216/10)=21 個位上的1的個數然後乘10。這裡再次把最後取到的十位數為1的單獨拿出來,即210~216要單獨考慮 ,個數為(216%10)+1 .這裡加8就避免了判斷的過程。
後面以此類推。
時間複雜度 o(logn)
解釋2//主要思路:設定整數點(如1、10、100等等)作為位置點i(對應n的各位、十位、百位等等),分別對每個數字上有多少包含1的點進行分析
//根據設定的整數字置,對n進行分割,分為兩部分,高位n/i,低位n%i
//當i表示百位,且百位對應的數》=2,如n=31456,i=100,則a=314,b=56,此時百位為1的次數有a/10+1=32(最高兩位0~31),每一次都包含100個連續的點,即共有(a%10+1)100個點的百位為1
//當i表示百位,且百位對應的數為1,如n=31156,i=100,則a=311,b=56,此時百位對應的就是1,則共有a%10(最高兩位0-30)次是包含100個連續點,當最高兩位為31(即a=311),本次只對應區域性點00~56,共b+1次,所有點加起來共有(a%10100)+(b+1),這些點百位對應為1
//當i表示百位,且百位對應的數為0,如n=31056,i=100,則a=310,b=56,此時百位為1的次數有a/10=31(最高兩位0~30)
//綜合以上三種情況,當百位對應0或》=2時,有(a+8)/10次包含所有100個點,還有當百位為1(a%101),需要增加區域性點b+1
//之所以補8,是因為當百位為0,則a/10(a+8)/10,當百位》=2,補8會產生進製位,效果等同於(a/10+1)
整數中1出現的次數(從1到n整數中1出現的次數)
求出1 13的整數中1出現的次數,並算出100 1300的整數中1出現的次數?為此他特別數了一下1 13中包含1的數字有1 10 11 12 13因此共出現6次,但是對於後面問題他就沒轍了。acmer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數。include u...
整數中1出現的次數(從1到n整數中1出現的次數)
時間限制 1秒 空間限制 32768k 題目描述 include using namespace std class solution 求之前的length 1位中含乙個數 int base1 0 int base2 1 for int i 0 i1 i cout cout cout 求從base2...
整數中1出現的次數(從1到n整數中1出現的次數)
求出1 13的整數中1出現的次數,並算出100 1300的整數中1出現的次數?為此他特別數了一下1 13中包含1的數字有1 10 11 12 13因此共出現6次,但是對於後面問題他就沒轍了。acmer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數。演算法一 暴力累加...