【题目描述】
【思路】
前缀和数组统计区间和
至少含有两个数 [a,b] a + b <=n 且要求a、b连续 b <= n / 2 + 1
那么枚举区间起点a和终点b
class Solution {
long s[] = new long[100010];
public List<List<Integer> > findContinuousSequence(int sum) {
int t = (sum >> 1 )+ 1; // 右移运算符比+优先级还弱 所以要加括号
for(int i = 1; i <= t ; i ++)
s[i] = s[i - 1] + i;
List<List<Integer> > ans = new ArrayList<>();
for(int b = 1; b <= t; b ++){
for(int a = 1; a < b; a ++){
long res = s[b] - s[ a - 1];
if(res == sum){
List<Integer> sub = new ArrayList<>();
for(int i = a; i <= b; i ++) sub.add(i);
ans.add(sub);
}
}
}
return ans;
}
}
【思路】
双指针 等差数列前n项和公式
class Solution {
public List<List<Integer> > findContinuousSequence(int sum) {
int t = (sum >> 1) + 1;
List<List<Integer> > ans = new ArrayList<>();
for(int i = 2, j = 1; i <= t;){
int res = (i + j) * (i - j + 1) /2;
if( res == sum ){
List<Integer> sub = new ArrayList<>();
int k = j;
while( k <= i) {
sub.add(k);
k ++;
}
ans.add(sub);
//相等则 i、j同时右移
i ++;
j ++;
}
//如果当前区间和较小则i右移
else if( res < sum) i ++;
else j ++;
}
return ans;
}
}
class Solution {
public List<List<Integer> > findContinuousSequence(int sum) {
// 至少由两个数组成 则最大值为sum/2 + 1
int n = sum/2 + 1;
// 前缀和数组
int s[] = new int[n + 1];
for (int i = 1; i <= n; i ++) {
s[i] = s[i - 1] + i;
}
List<List<Integer>> ans = new ArrayList<>();
// 枚举区间结尾端点
for (int i = n, j = i - 1; i >= 2 && j >= 0;) {
if (s[i] - s[j] == sum) { // 区间 [j + 1, i]符合条件
List<Integer> sub = new ArrayList<>();
for (int k = j + 1; k <= i; k ++) sub.add(k);
ans.add(sub);
i --;
} else if (s[i] - s[j] < sum) { //区间[J+1, i]之和小于sum,j --
j --;
} else {
i --;
}
}
return ans;
}
}