從1到n整數中1出現的個數

今天在牛客網上做劍指offer上的題,看到劍指offer上的解法確實沒不太好理解。這裏把看到的一種比較容易理解的方法記錄下來,便於整理思路:

原博客解釋的非常清楚,在這裏。

這道題是要求1-n,這裏總共出現了多少次1。

比如輸入爲12,則包含1的數字有1,10,11,12總共出現了五次。

那我們就從這個例子開始吧(本文會按照原文的記號來說明):

round=n/10,weight=n%10

首先我們來看個位:

12

如果只有2的話,出現了一次,記錄一下count=0+1=1;

12

再到十位,十位爲1,個位數字變化的只有0,1,2再加上本身的1位1,總共4次。那麼總共會出現的次數爲count=count+4=5

這個例子比較簡單,也不能說明什麼規律,再看一個例子:

678

首先是個位,

678,round=67(代表高位可以從0~9變化67次),base=1(代表當前在個位),weight=8(代表當前位的權重),count=0

那麼這時的高位可以循環67次,代表可以有67次個位數1的數字,加上個位數自己的一次總共爲count=67+1=68次。

678,round=6,base=10(十位),weight=7,count=68

此時,高位可以循環的有6*10=60次,7大於1,十位數爲1的也可以完全出現,所以count=count+6*10+10=138次

678,round=0,base=100(百位),weight=6,count=68

此時已經沒有比百位更高的位了,但是6是大於1的,所以可以出現1*100次完整的百位1,所以共計count=count+100=238次。

結束。

需要注意的是,出現多少次1和當期的weight是相關聯的,若當前爲weight=0,則不貢獻任何1,即爲前面的count。若當前爲1,如17,則可以貢獻個位數個數爲former(7)+1次,若大於1的話,意味着可以貢獻weight*base+base(當前weight位取1)個。


所以分爲三種情況:

當前weight=0:count=round*base

當前weight=1:count=roung*base+former+1

當前weight>1:count=round*base+base

public int NumberOf1Between1AndN_Solution(int n) {
			int count =0;
			int base=1;
			int round=n;
			while(round>0){
				int weight=round%10;
				round/=10;
				count+=round*base;//公共部分
				if(weight==1)
					count+=(n%base)+1;
				else if(weight>1)
					count+=base;
				base*=10;
			}
	    	return count;
    }


發佈了56 篇原創文章 · 獲贊 103 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章