題目描述
求出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