一個自然數拆分成連續自然數的和


1. 能否拆分

    結論:除了 $2^n$ 之外,其他自然數均可以拆分

    所有奇數都能寫成 $2i + 1$ 的形式,因此至少可以拆成 $(i, i+1)$,所以奇數可以拆分

    偶數里邊,奇數倍數的可以拆分,其他的(也就是 $2^n$) 無法拆分

 1 boolean ifConsistOfConsecutiveInteger(int n) {
 2     if (n <= 0) {
 3         return false;
 4     }
 5     boolean result = false;
 6     if ((n & (n - 1)) != 0) {
 7         result = true;
 8     }
 9 
10     return result;
11 }

2. 輸出可以拆分成的各種形式

    2.1 數學方法

          以 $a$ 表示連續自然數中的第一個,則

          $n = a + (a + 1) + (a + 2) + ... + (a + k - 1)$

          整理一下

          $2n = 2ka + k^2 - k$

          整理成關於 $k$ 的一元二次方程

     $k^2 + (2a - 1)k - 2n = 0$

     解這個方程,$\Delta = (2a -1)^2 + 8n$

   $k = (1 - 2a + \sqrt{\Delta})/2$

      然后,考慮三個問題

      1) 連續自然數序列里的第一個數必然小於等於 $n/2$,如果大於的話,再和后面的數相加肯定大於 $n$

      2) $\Delta$ 開方之后必須是整數

      3) $1 - 2a + \sqrt{\Delta}$ 必須是偶數,否則除以 $2$ 會出現小數

    代碼如下($n$ 太大時不適用,會有溢出):

 1 void printExpression(int n) {
 2     long first;
 3     long incr;
 4     for (int i = 1; i <= n / 2; i++) {
 5         first = i;
 6         long delta = (2 * first - 1) * (2 * first - 1) + 8 * n;
 7         long sqrt_delta = (int) Math.sqrt(delta);
 8 
 9         if (sqrt_delta * sqrt_delta == delta && sqrt_delta % 2 != 0) {
10             incr = (sqrt_delta - (2 * first - 1)) / 2;
11             System.out.println("num of consecutive integer is " + incr);
12             for (int j = 1; j <= incr; j++) {
13                 System.out.print(first + j - 1 + " ");
14             }
15             System.out.println();
16         }
17     }
18 }

     2.2 雙指針解法(參考劍指 Offer)

 1 void printExpression2(int n) {
 2     int small = 1;
 3     int big = 2;
 4     int sum = small + big;
 5     while (small <= n / 2) {
 6         if (sum == n) {
 7             for (int i = small; i <= big; i++) {
 8                 System.out.print(i + " ");
 9             }
10             System.out.println();
11         }
12         while (sum > n) {
13             sum -= small;
14             small++;
15 
16             if (sum == n) {
17                 for (int i = small; i <= big; i++) {
18                     System.out.print(i + " ");
19                 }
20                 System.out.println();
21             }
22         }
23 
24         big++;
25         sum += big;
26     }
27 }

 


免責聲明!

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



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