连续整数求和

原题:https://leetcode-cn.com/problems/consecutive-numbers-sum/

题意:给定一个正整数 n,返回 连续正整数满足所有数字之和为 n 的组数 

比如:

 

输入: n = 5
输出: 2
解释: 5 = 2 + 3,共有两组连续整数([5],[2,3])求和后为 5。

 

直接放三种常规analysis和code:

 

class Solution
{
public:
    int consecutiveNumbersSum(int n)
    {
        /*
        1.枚举
            枚举初始值直到大于
            o(n^(3/2))

        2.简单数学
            假设k个连续的正整数之和为N:
                N=(x+1)+(x+2)+...+(x+k) , x>=0 , k>=1
                得到:N=kx+k*(k+1)/2
                x=N/k-(k+1)/2
                枚举k,[1,2N] 计算x=N/k-(k+1)/2
                如果x为正整数, 那么即为一组解
            o(n)

        3.进阶数学
            由 N=kx+k*(k+1)/2
            得2N=k*(2x+k+1)
            在2N=k*(2x+k+1)中,有k<2x+k+1
            因此,枚举k实际范围只需要[1,(2n)^(1/2)]

            继续简化x=N/k-(k+1)/2
            此时内部有个N/k也需要条件语句,所以继续转换
            x=(N-k*(k+1)/2)/k
            由于k*(k+1)%2==0是一定的
            那么只需要外部 "/k" 保证整数即可
            所以直接有ans+=(n-(k+1)*k/2)%k==0
            over
        */
        int ans = 0;
        for (int k = 1; k <= sqrt(2 * n); ++k)
            ans += (n - (k + 1) * k / 2) % k == 0;
        return ans;
    }
};
三种

 

一个神仙巧解:

    # 1个数时,必然有一个数可构成N

        # 2个数若要构成N,第2个数与第1个数差为1,N减掉这个1能整除2则能由商与商+1构成N
        # 3个数若要构成N,第2个数与第1个数差为1,第3个数与第1个数的差为2,N减掉1再减掉2能整除3则能由商、商+1与商+2构成N
        # 依次类推,当商即第1个数小于等于0时结束

 

 

class Solution
{
public:
    int consecutiveNumbersSum(int n)
    {
        int ans = 0;
        for (int i = 1; n > 0; n -= i, i++)
            ans += (n % i == 0);
        return ans;
    }
};
数学大佬

 

 

 

 

posted @ 2022-02-21 17:35  Renhr  阅读(446)  评论(0)    收藏  举报