求1到N的所有整數中「1」的個數

2021-06-22 14:00:12 字數 2143 閱讀 1234

題意:給定乙個十進位制的整數n,求1到n的所有整數中「1」出現的個數

解題思路:最簡單的一種方法是對1到n中的每個整數的每一位進行判斷,使用除法與取餘的方式,這種方法的時間複雜度是o(n*logn)

解法一:

程式設計之美中通過分析,總結了這樣的乙個規律:

假設要處理的資料n=abcde,現在要計算百位上出現1的次數,則它受三個因素的影響:百位上的數字(icurnum)、百位以上的數字(ihighernum)、百位以下的數字       (ilowernum)

(1)如果icurnum = 0, 則百位上可能出現1的次數由更高位決定,等於更高位數字乘以當前位數(ihighernum * 100)

(2)如果icurnum = 1, 則百位上可能出現1的次數不僅由更高位決定,還受低位的影響。等於更高位數字乘以當前位數+低位數字+ 1(ihighernum * 100 +ilowernum + 1)

(3)如果icurnum > 1,則百位上可能出現1的次數僅由更高位決定,等於(更高位數字+1)* 當前位數((ihighernum + 1) * 100)

int numberof1between1ton(int n)

int icount = 0;

int factor = 1;

int ilowernum, icurnum, ihighernum;

while(n / factor)

factor *= 10;

}return icount;

}

解法二:(來自劍指offer)

以21345作為例子分析,將21345分為兩部分:1~1345、1346~21345。

先處理1346~21345。首先考慮萬位上(最高位)出現1的個數,由於最高位是2,因此1出現在10000~19999中,共10000個數。這裡要注意一點,當最高位是1時,比如為11345,此時1的個數就不是10000了,而是1345+1,即除去最高位數字之後再加上1。而如果最高位是1,則1的個數就為0

接下來處理1346~21345中除去最高位後,後面4位中1的個數。由於最高位是2,因此可以將1346~21345分為兩段:1346~11345、11346~21345。由於最高位已經考慮了,因此判斷1346~11345、11346~21345中剩下1的個數等價於判斷(1346~9999,0000~1345;1346~9999,0000~1345)中1的個數,也就是判斷0~9999中1的個數,之後再用最高位乘以0~9990中1的個數。

對0~9999中1個數可以分析個、十、百、千位上分別為1的個數,然後求和。當個位為1時,十、百、千位上的數字可以在0~9中隨意選擇,根據排列組合就有10*10*10種,同理當

十、百、千位為1時,也會有這麼多組合,因此就為4*10*10*10種組合,也就是10的(位數減1)次方 * 位數

到此1346~21345就處理完了。

之後處理1345,可以按照處理21345的方式進行處理,即遞迴處理,之後將各部分結果相加即為總的結果。

int powerbase10(unsigned int n)

return result;

}int numberofone(string &str, unsigned int pos)

int numfirstdigit = 0;

if(str[pos] > '1')

numfirstdigit = powerbase10(str.size() - pos - 1);

else if('1' == str[pos])

numfirstdigit = atoi(str.substr(pos + 1, str.size() - pos - 1).c_str()) + 1;

int numotherdigit = (str[pos] - '0') * (str.size() - pos - 1) * powerbase10(str.size() - pos - 2);

int numrecursive = numberofone(str, pos + 1);

return numfirstdigit + numotherdigit + numrecursive;

}int numberofonebetween1ton(int n)

統計從1到N的所有整數中出現1的個數

問題 給定乙個十進位制的正整數n,寫下從1開始到n的所有整數,然後數一下其中出現的所有 1 的個數。解 假設n abcde,這裡abcde分別是十進位制數n的各個數字上的數字。例如我們計算百位上出現1的次數,它將會受到三個因素的影響 百位上的數字,百位一下,百位以上的數字。對於2位數來說,個位數出現...

計算從整數1到n之間,所有1的個數的和

整數中1的個數 計算從整數1到n之間,所有1的個數的和 c include using namespace std int numberof1between1andn solution int n return ones int main 通過使用乙個 位置乘子m 遍歷數字的位置,m 分別為1,10...

求整數中1的個數

public static int bitcount int i int型別是有符號型別的特點,當最高位為1時,表示乙個負值。利用這一特點,通過左移位操作 然後判斷正負值,為負標明該位為1,正值標明該位為0。如下。public static int bitcount int i return cou...