演算法系列之三十二 1的數目

2021-10-01 17:02:15 字數 1623 閱讀 2806

題目

for example:

given n = 13,

return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

思路一

這個問題看上去並不是乙個困難的問題,因為不需要太多的思考,我想大家都能找到乙個最簡單的方法來計算f(n),那就是從1開始遍歷到n,將其中每乙個數中含有「1」的個數加起來,自然就得到了從1到n所有「1」的個數的和。

這個方法很簡單,只要學過一點程式設計知識的人都能想到,實現也很簡單,容易理解。但是這個演算法的致命問題是效率,它的時間複雜度是o(n)×計算乙個整數數字裡面「1」的個數的複雜度 = o(n * log2 n)。如果給定的n比較大,則需要很長的運算時間才能得到計算結果。比如在筆者的機器上,如果給定n=100 000 000,則算出f(n)大概需要40秒的時間,計算時間會隨著n的增大而線性增長。

看起來要計算從1到n的數字中所有1的和,至少也得遍歷1到n之間所有的數字才能得到。那麼能不能找到快一點的方法來解決這個問題呢?要提高效率,必須擯棄這種遍歷1到n所有數字來計算f(n)的方法,而應採用另外的思路來解決這個問題。

**一

/*---------------------------------------

* 日期:2015-07-18

* 題目: 233.number of digit one

* **:

* 結果:超時

* 部落格:

-----------------------------------------*/

#include #include using namespace std;

class solution //if

if(n <= 0)//if

int result = 1;

for(int i = 10;i <= n;++i)//for

return result;

}private:

// 計算num中1的個數

int digitone(int num)//if

num /= 10;

}//while

return result;

}};int main()//if

int result = 0;

int lowernum = 0,curnum = 0,highnum = 0;

int base = 1;

int num = n;

while(num)//if

// 如果為1則這一位1出現的次數不僅受更高位影響還受低位影響(更高位數字*當前位數+低位數字+1)

else if(curnum == 1)//else

// 大於1則僅受更高位影響((更高位數字+1)*當前位數)

else//else

num /= 10;

base *= 10;

}//while

return result;

}};int main()//while

return 0;

}

USACO演算法系列三十二 job

題目 http www.nocow.cn index.php translate usaco job 很有意思的一道題目,乙個產品要經過a,b兩道工序,a系列機器加工時間為a1,a2,a3,a4 b系列工序的處理時間為b1,b2,b3,要求a,b系列處理完這些產品 n 時間最短。第一道工序很簡單,使...

樹演算法系列之三 GBDT

gbdt與提公升樹有非常密切的關係。為方便閱讀本文,可以先參考提公升樹一文。在提公升樹一文中,我們提到每一輪迭代,都是去擬合上一輪的 殘差 如果用乙個簡單的公式表示就是yi fm 1 x y i f x yi fm 1 x gbdt與上面普通提公升樹的不同在於,其擬合的不是殘差,而是梯度下降的方向。...

演算法系列之三 單鏈表反轉

問題 實現單鏈表反轉 答案 鍊錶準備 class node public int getdata public void setdata int data public node getnext public void setnext node next public static void mai...