題目
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...