Java&C++题解与拓展——leetcode829.连续整数求和【么的新知识】

167 阅读1分钟
每日一题做题记录,参考官方和三叶的题解

题目要求

在这里插入图片描述

思路:数论

  • 连续段之和得到nn,那么可以找到一个长度为kk的连续段,其首项为aa,三者之间满足一些关系以构成答案。
    • 具体来说,由等差数列求和公式得(a+a+k1)×k2=n\frac{(a+a+k-1)\times k}{2}=n
    • 变换可得,2a=2nkk+122a=\frac{2n}{k}-k+1\ge 2
    • 也就是说,2nkk+12nk>k\frac{2n}{k}\ge k+1\Leftrightarrow \frac{2n}{k}\gt k
    • kk必然是2n2n的约数,且是较小的那一方,所以枚举kk并判断等差数列和即可。

Java

class Solution {
    public int consecutiveNumbersSum(int n) {
        int res = 0;
        n *= 2;
        for(int k = 1; k * k < n; k++) {
            if(n % k != 0)
                continue;
            if((n / k - (k - 1)) % 2 == 0)
                res++;
        }
        return res;
    }
}
  • 时间复杂度:O(2n)O(\sqrt{2n})
  • 空间复杂度:O(1)O(1)

C++

class Solution {
public:
    int consecutiveNumbersSum(int n) {
        int res = 0;
        n *= 2;
        for(int k = 1; k * k < n; k++) {
            if(n % k != 0)
                continue;
            if((n / k - (k - 1)) % 2 == 0)
                res++;
        }
        return res;
    }
};
  • 时间复杂度:O(2n)O(\sqrt{2n})
  • 空间复杂度:O(1)O(1)

Rust

  • 换了一个复杂度更低的高赞方式;
  • 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时结束
impl Solution {
    pub fn consecutive_numbers_sum(n: i32) -> i32 {
        let mut res = 0;
        let mut k = 1;
        let mut n = n;
        while n > 0 {
            n -= k;
            if n % k == 0 {
                res += 1;
            }
            k += 1;
        }
        res
    }
}
  • 时间复杂度:O(n)O(\sqrt{n})
  • 空间复杂度:O(1)O(1)

总结

数学理论分析更重要的题。


欢迎指正与讨论!