题目
给定一个正整数 n
,返回 连续正整数满足所有数字之和为
n
的组数 。
示例 1:
输入: n = 5
输出: 2
解释: 5 = 2 + 3,共有两组连续整数([5],[2,3])求和后为 5。
示例 2:
输入: n = 9
输出: 3
解释: 9 = 4 + 5 = 2 + 3 + 4
示例 3:
输入: n = 15
输出: 4
解释: 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5
提示:
- \(1 <= n <= 10^{9}\)
题解
枚举
众所周知,以正整数 \(a\) 为起点的连续 \(k\) 个数字之和可以使用等差数列求和公式计算:
\[ \begin{aligned} n &= \dfrac{(a + (a + k - 1)) \times k}{2} \\ &= \dfrac{(2a + k - 1) \times k}{2} \end{aligned} \]
从题目中得知,我们已知和为 \(n\), 那么就要求上述方程的正整数解,但有两个未知数 \(a, k\),一种简单的思路是:枚举其中一个数,那么另外一个数字就能计算出来了,我们只需验证得到的解是否合法即可,这里的合法是指解出的 \(a, k\) 应该是正整数。
相比之下,枚举连续数字的个数 \(k\) 比枚举起点 \(a\) 要容易一些,将公式变形,即
\[ a = \dfrac{\cfrac{2n}{k} + 1 - k}{2} \]
那么还剩下一个问题是,枚举到什么时候终止呢?换而言之,\(k\) 最大取值是多少?
不难发现,在和一定的情况下,以 \(1\) 为起点得到的数列是最长的,即 \(a = 1\) 代入时得到的 \(k\) 最大,所以当我们计算到 \(a < 1\) 即可终止。
1 | # Code language: Python |
1 | // Code language: Java |
1 | // Code language: C++ |
1 | // Code language: C |
1 | // Code language: C# |
- 时间复杂度:\(O(\sqrt{n})\), 易得 \(k^2 +(2a - 1)k = 2n \Rightarrow k^2 \leq 2n \Rightarrow k \leq \sqrt{2n}\)
- 空间复杂度: \(O(1)\)
最后
如果对你有帮助的话,请给我点个赞吧~