劍指offer-整數中1出現的次數(python和c++)

題目描述

求出113的整數中1出現的次數,並算出1001300的整數中1出現的次數?爲此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對於後面問題他就沒轍了。ACMer希望你們幫幫他,並把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數(從1 到 n 中1出現的次數)。

這道題有點繞,下面是我看過的最好懂的解釋。

/*
設N = abcde ,其中abcde分別爲十進制中各位上的數字。
如果要計算百位上1出現的次數,它要受到3方面的影響:百位上的數字,百位以下(低位)的數字,百位以上(高位)的數字。
① 如果百位上數字爲0,百位上可能出現1的次數由更高位決定。比如:12013,則可以知道百位出現1的情況可能是:100199,11001199,21002199,,…,1110011199,一共1200個。可以看出是由更高位數字(12)決定,並且等於更高位數字(12)乘以 當前位數(100)。
② 如果百位上數字爲1,百位上可能出現1的次數不僅受更高位影響還受低位影響。比如:12113,則可以知道百位受高位影響出現的情況是:100199,11001199,21002199,,…,1110011199,一共1200個。和上面情況一樣,並且等於更高位數字(12)乘以 當前位數(100)。但同時它還受低位影響,百位出現1的情況是:12100~12113,一共114個,等於低位數字(113)+1。
③ 如果百位上數字大於1(29),則百位上出現1的情況僅由更高位決定,比如12213,則百位出現1的情況是:100199,11001199,21002199,…,1110011199,1210012199,一共有1300個,並且等於更高位數字+1(12+1)乘以當前位數(100)。
*/

還是提供python和c++的代碼。

python

class Solution:
    def NumberOf1Between1AndN_Solution(self, n):
        # write code here
        #循環的出口是 highValue = 0
        #我們從最低位開始一個位一個位的來尋找 1 的可能出現的 情況次數。
        # 一開始 精準度爲1.高位低位中位 先賦值爲1.
        preceise = 1
        highValue = 1
        lowValue = 1
        midValue =1
        #計數 後面的位數。
        count = 0
        #計數 1 的次數和
        sumNum = 0
        #循環的 出口是我們找不到最高位了,那麼這個時候就說明,我們遍歷到了 這個數字的最高位。
        while highValue != 0:
            #高位 先將這個數 除以10 得到高位
            highValue = n // (preceise * 10)
            #中位 先將這個數  與 10 取餘。
            midValue = (n // preceise)%10
            #低位 先將這個數 除以 1 那麼低位就是個位後面的,沒有就是0.
            lowValue = n % preceise
            #每遍歷一次 向右移一位,那麼就是說 精準度要乘以10.
            preceise *= 10
			#如果這個數是0 的話,
            
            if midValue == 0:
                #那麼它就是高位的值,乘以 10^後面的位數 次方,但是這個時候 對於中位 來說 它是個位,後面沒有位,所以是0,
                num = (highValue)* pow(10,count)
            #如果這個數 大於1 的話,
            elif midValue > 1:
                #那麼它 就是 最高位加1 乘以 10^後面的位數 次方,
                num = (highValue+1)*pow(10,count)
            else:
                #否則的話 它就是等於1 的情況了,對於等於1 的1情況,又是比較特殊的情況,它需要 最高位 * 它10 的後面位數個數的次方,然後要加上我們低位 的數值再加 1, 原因在上面的分析中已經給出。
                num = highValue*pow(10,count)+(lowValue+1)
            #最後 我們1 出現的 次數 就是這 三個 num 的和,。
            sumNum += num
            #沒循環一次,這個三個就往左移一次嗎,那麼這個時候它們 後面的位數也就會 多一位。
            count += 1
		#最後返回這個次數和。
        return sumNum

c++

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        int count=0;
        if(n<1) return 0;
        for(int i=1;i<=n;++i)
            {
            int temp=i;
            while(temp)
                {
                if(temp%10==1)
                    ++count;
                temp/=10;
            }
        }
        return count;
    }
};

更加詳細的講解視頻:
https://www.bilibili.com/video/BV1K4411o7KP?t=508&p=23

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章