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.