LeetCode 829. Consecutive Numbers Sum–B站笔试题–C++解法
LeetCode题解专栏:LeetCode题解
我做的所有的LeetCode的题目都放在这个专栏里,大部分题目Java和Python的解法都有。
题目地址:Consecutive Numbers Sum - LeetCode
Given a positive integer N, how many ways can we write it as a sum of consecutive positive integers?
Example 1:
Input: 5
Output: 2
Explanation: 5 = 5 = 2 + 3
Example 2:
Input: 9
Output: 3
Explanation: 9 = 9 = 4 + 5 = 2 + 3 + 4
Example 3:
Input: 15
Output: 4
Explanation: 15 = 15 = 8 + 7 = 4 + 5 + 6 = 1 + 2 + 3 + 4 + 5
Note: 1 <= N <= 10 ^ 9.
这道题目是2019-9-10的B站笔试原题,可惜我没有事先看到,听别人在牛客网上说才知道的。
这道题目最容易想到的解法就是暴力穷举,时间复杂度O(N^2),肯定超时。
使用等差数列,可以快一些:
C++解法如下:
class Solution {
public:
int consecutiveNumbersSum(int N) {
int result = 1;
int a = N;
int temp;
for (int i = 1; i < a / 2 + 1; i++) {
for (int j = i + 1; j <= a - i; j++) {
temp = (i + j) * (j - i + 1) / 2;
if (temp == a) {
result += 1;
break;
} else if (temp > a) {
break;
}
}
}
return result;
}
};
但上面的做法会超时,换一个思路,首项是x,有m项,那么[x + (x + (m-1))]m / 2
->x*m+m*(m-1)/2=n
,只要遍历m从1到sqrt(n)即可。
C++解法如下:
class Solution {
public:
int consecutiveNumbersSum(int N) {
int ans = 0;
for (int m = 1;; m++) {
int m_x = N - m * (m - 1) / 2;
if (m_x <= 0)
break;
if (m_x % m == 0)
ans++;
}
return ans;
}
};
更快的C++解法如下:
class Solution {
public:
int consecutiveNumbersSum(int N) {
int sum = 0, ans = 0;
for(int i = 1; sum < N; i++) {
sum += i;
if (((N-sum) % i) == 0)
ans++;
}
return ans;
}
};
思路是:
let N = k + (k+1) + (k+2) + (k+3) + … + (k+i-1) = ik + (1+2+3+… + i-1)
let sum(i) = (1+2+3+…+i-1), then we have
N = sum(i) + ik ==>i*k = N - sum(i)
Which means: for each i, we can calculate N-sum(i). If N-sum(i) can be divided by i, there is an answer with length i.