如12出現1的次數爲5,分別是:1,10,11,12優化
通常作法:從1-n遍歷,計算每個數中每一位出現1的次數spa
function count(num){ var n=0; for(var i=1;i<=num;i++){ n+=Number(i); } console.log(n); } function Number(i){ var number=0; while(i!=0){ if(i%10==1){ number+=1; } i=parseInt(i/10); } return number; } var num=1234; count(num);
這種作法對每個數字都要作除法和求餘運算,以求出該數字中1出現的次數。可是當輸入的n很是大時須要大量的計算,運算效率不高。因此須要進行優化。code
法二:分析規律 計算每一位出現1的次數blog
(1)1位數狀況it
如n=5; 出現1的次數爲1io
(2)2位數的狀況console
如n=13function
個位上出現1的有:1,11class
十位上出現1的有:10,11,12,13效率
f(n)=2+4=6;
如n=23
個位出現1的有:1,11,21
十位出現1的有:10,11,12,13,14,15,16,17,18,19
f(n)=3+10=13
經過對兩位數進行分析,咱們發現:
個位出現1的次數不只和個位數字有關,還和十位數字有關;若是n的個位數大於等於1,則個位出現1的次數爲十位數字加1;
若是個位數字爲0,則個位出現1的次數等於十位的數字;
而十位出現1的次數不只和十位數有關,還和個位數有關;若是十位數等於1,則十位數出現1的次數爲個位數的數字加1,若是十位數大於1,則十位數出現1的次數爲10;
(3)3位數的狀況
如n=123;
個位出現1的次數13:1,11,21,。。。91,101,111,121
十位出現1的次數20:10-19,110-119
百位出現1的次數24:100-123
f(n)=13+20+24
若是要計算百位上出現1的次數,它受三方面影響:百位上的數字,百位如下的數字以及百位以上的數字
若是百位上數字爲0,百位上可能出現1的次數由更高位決定。好比:12013,則能夠知道百位出現1的狀況多是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200個。能夠看出是由更高位數字(12)決定,而且等於更高位數字(12)乘以 當前位數(100)。
若是百位上數字爲1,百位上可能出現1的次數不只受更高位影響還受低位影響。好比:12113,則能夠知道百位受高位影響出現的狀況是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200個。和上面狀況同樣,而且等於更高位數字(12)乘以 當前位數(100)。但同時它還受低位影響,百位出現1的狀況是:12100~12113,一共114個,等於低位數字(113)+1。
若是百位上數字大於1(2~9),則百位上出現1的狀況僅由更高位決定,好比12213,則百位出現1的狀況是:100~199,1100~1199,2100~2199,...........,11100~11199,12100~12199,一共有1300個,而且等於更高位數字+1(12+1)乘以當前位數(100)。
function num1(n){ var count=0;//個數 var curBit=1;//當前位 var lowerNum=0;//低位數字 var curNum=0;//當前位數字 var higherNum=0;//高位數字 if(n<=0){ return 0; } while(parseInt(n/curBit)!=0){ lowerNum=n-parseInt(parseInt((n/curBit))*curBit); curNum=parseInt((n/curBit)%10); higherNum=parseInt(n/(curBit*10)); //若是當前位爲0,出現1的次數由高位決定 if(curNum==0){ //等於高位數字乘當前位數 count+=higherNum*curBit; } //若是當前位爲1,出現1的次數由高位和低位決定 else if(curNum==1){ //等於高位數字*當前位數+低位數字+1 count+=higherNum*curBit+lowerNum+1; } //若是大於1,出現1的次數由高位決定 else{ //(高位數字+1)*當前位數 count+=(higherNum+1)*curBit; } //位數向前移一位 curBit*=10; } return count; } console.log(num1(1234));