[劍指offer題解][Java]1到n整數中1出現的次數

前言

衆所周知,《劍指offer》是一本「好書」。java

若是你是個算法菜雞(和我同樣),那麼最推薦的是先把劍指offer的題目搞明白。git

對於劍指offer題解這個系列,個人寫做思路是,對於看過文章的讀者,可以作到:github

  • 迅速瞭解該題常看法答思路(偏門思路不包括在內,節省你們時間,實在有研究需求的人能夠查閱其它資料)
  • 思路儘可能貼近原書(例如書中提到的面試官常常會要求不改變原數組,或者有空間限制等,儘可能體如今代碼中,保證讀者能夠不漏掉書中細節)
  • 儘可能精簡話語,避免冗長解釋
  • 給出代碼可運行,註釋齊全,關注細節問題
  • 代碼可以經過牛客網在線編程《劍指offer》測試

《劍指offer題解》系列

你能夠經過如下兩種途徑查看《劍指offer題解》系列:面試

題目介紹

求出1 ~ 13的整數中1出現的次數,並算出100 ~ 1300的整數中1出現的次數?爲此他特別數了一下1 ~ 13中包含1的數字有一、十、十一、十二、13所以共出現6次,可是對於後面問題他就沒轍了。ACMer但願大家幫幫他,並把問題更加廣泛化,能夠很快的求出任意非負整數區間中1出現的次數(從1 到 n 中1出現的次數)。算法

解題思路

方法一:遞歸每一個數字

思路

思路很簡單,寫個for循環,從1到n,在循環體中判斷這個數包含了多少個1編程

複雜度O(nlogn),面試官不怎麼開心呢。。後端

方法二:找規律

思路

思路解釋參考:數組

www.nowcoder.com/profile/337…安全

設N = abcde,其中abcde分別爲十進制中各位上的數字。微信

若是要計算百位上1出現的次數,它要受到3方面的影響:百位上的數字,百位如下(低位)的數字,百位以上(高位)的數字。

①若是百位上數字爲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)。

代碼

public int NumberOf1Between1AndN_Solution(int n) {

    //1的個數
    int count = 0;

    //當前位
    int i = 1;

    int current, after, before;

    while((n/i)!= 0){

        //高位數字
        current = (n/i)%10;
        //當前位數字
        before = n/(i*10);
        //低位數字
        after = n-(n/i)*i;

        //若是爲0,出現1的次數由高位決定,數量等於高位數字 * 當前位數
        if (current == 0) {
            count += before * i;
        } else if(current == 1) {
            //若是爲1,出現1的次數由高位和低位決定,高位*當前位+低位+1
            count += before * i + after + 1;
        } else{
            //若是大於1,出現1的次數由高位決定,(高位數字+1)* 當前位數
            count += (before + 1) * i;
        }
        //前移一位
        i = i*10;
    }
    return count;
}
複製代碼

總結

此題思考再三,想分析做者爲何要出此題,該題出如今優化時間和空間效率大類中,做者主要是想讓同窗們運用邏輯推理,想到時間上更優化的解法。

《劍指offer題解》系列

你能夠經過如下兩種途徑查看《劍指offer題解》系列:

關注我

我是一名後端開發。主要關注後端開發,數據安全,爬蟲等方向。微信:yangzd1102

Github:@qqxx6661

我的博客:

原創博客主要內容

  • Java知識點複習全手冊
  • Leetcode算法題解析
  • 劍指offer算法題解析
  • SpringCloud菜鳥入門實戰系列
  • SpringBoot菜鳥入門實戰系列
  • Python爬蟲相關技術文章
  • 後端開發相關技術文章

我的公衆號:Rude3Knife

我的公衆號:Rude3Knife

若是文章對你有幫助,不妨收藏起來並轉發給您的朋友們~

相關文章
相關標籤/搜索