經典題:一個整數分解為連續正整數之和


為了找份暑期實習生的工作,今天去某公司面試。很喜歡這樣的公司,首先不問出身、不問愛好,直接給你一台電腦,幾道編程題目,讓你寫程序。

其中有道題目是將一個整數分解為連續正整數之和,如15可以分解為:

15 = 1 + 2 + 3 + 4 + 5

15 = 4 + 5 + 6

15 = 7 + 8

這道題,我用最死板的方法給編出來了。輸入數n,設置起始位置i,再遍歷連續正整數的長度k,由公式計算出 sum = i + (i+1) + ... + (i+k) = (k+1) * (2*i + k) / 2,判斷與n的關系,若相等則打印出從i到i+k這(k+1)個數;若sum>n,則break;

偽碼如下:

for  (i = 1; i <= n/2; i++)
    for  (k = 1;  ; k++)
        sum = (k+1) * (2*i + k) / 2;
            if (sum > n)
                break;
            if (sum == n)
                print (從i到i+k的值)

 

但這算法的復雜度高呀!達到O(n2)!肯定不是最好的方法,回來我在網上找了一下這個題目,發現有很多解法,說一個比較容易理解的吧。

我們計算從i開始連續k個數之和的計算公式如下:

                          sum = k * (2 * i + k - 1) / 2;

現在題目要求sum == n 的所有可能情況,上面的解法是從起始位置開始循環,又根據連續個數循環,兩重循環,那么從上面的公式逆向想想,如果sum==n時,i與k直接滿足什么關系呢?有 k * (2 * i + k - 1) = 2 * n。那么如果用k循環,計算出起始位置 i = ( 2*n / k - k + 1) / 2,豈不是時間復雜度降到線性的了。如下:

for (k = 1; k <= n/2; k++)
    if (2*n % k == 0)      //能被k整除
        temp = 2*n / k - k + 1;
        if (temp % 2 == 0)      //能被2整除
            i = temp / 2;
            print (從i到i+k-1的值)

 

ok! 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM