Loading

笔试题 · 正整数分解为几个连续自然数之和

题目

输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列。 一个正整数有可能可以被表示为n(n>=2)个连续正整数之和,如:
  15 = 1 + 2 + 3 + 4 + 5
  15 = 4 + 5 + 6
  15 = 7 + 8

解题思路

i + (i+1) + ··· + (i+k) = n ,这个等式表明了i,k,n三者之间的数学关系。
给定n值,遍历i,k中的某一值就可以得出另外一值,从而确定i到(i+k)之间的连续序列是符合要求的。

时间复杂度

O(n)

Java实现

/**
 *  题目:
 *      输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列。
 *      一个正整数有可能可以被表示为n(n>=2)个连续正整数之和,如:
 *      15 = 1 + 2 + 3 + 4 + 5
 *      15 = 4 + 5 + 6
 *      15 = 7 + 8
 *
 *  n = 99
 *      49  50
 *      32  33  34
 *      14  15  16  17  18  19
 *      7   8   9   10  11  12  13  14  15
 *      4   5   6   7   8   9   10  11  12  13  14
 *
 *  解题思路:
 *      i + (i+1) + ··· + (i+k) = n   =>   (2i+k)*(k+1)=2n ,这个等式表明了i,k,n三者之间的数学关系,
 *      给定n值,遍历i,k中的某一值就可以得出另外一值,从而确定i到(i+k)之间的连续序列是符合要求的
 *
 *  时间复杂度:O(n)
 */
public class IntegerSplitContinueInteger {
    public static void main(String[] args) {
        int n = 99;
        split(n);
    }
 
    private static void split(int n) {
        for (int k = 1; k <= n / 2; ++k) {
            if ((2 * n) % (k + 1) == 0) {
                int t = (2 * n) / (k + 1) - k;
                if (t <= 0) {
                    break;
                }
                if (t % 2 != 0) {
                    continue;
                }
                int i = t / 2;
                print(i, k);
            }
        }
    }
 
    private static void print(int i, int k) {
        for (int j = i; j <= i + k; ++j) {
            System.out.printf("%d\t", j);
        }
        System.out.println();
    }
}
posted @ 2020-08-10 17:26  dai.sp  阅读(1338)  评论(0编辑  收藏  举报