int left = 1;
int right = 2;
int sum = left + right;
List<int[]> vec = new ArrayList<int[]>();
while(left <= target/2) {//最少两个数,因此left最大值也就是target的一半
if(sum == target) {
//返回结果
int[] res = new int[right - left + 1];
for(int i = 0; i <= right - left; i++) {
res[i] = left + i;
}
vec.add(res);
}
if(sum < target) {
right++;
sum += right;//小于 的时候right右移,sum+right
}
else {
sum -= left;//大于 等于 的时候left右移,sum-left,这样避免多次计算sum
left++;
}
}
return vec.toArray(new int[vec.size()][]);
// 求和公式
class Solution {
public int[][] findContinuousSequence(int target) {
int i = 1;// 从1开始遍历计算左右边界i、j
double j = 2.0;
List<int[]> list = new ArrayList<>();
while (i < j) {
j = (-1 + Math.sqrt(1 + 4 * (2 * target + (long) i * i - i))) / 2;
int r = (int) j;
if (i < j && j == r) {// 只取整数
int[] sub = new int[r - i + 1];
for (int k = i; k <= r; k++) {
sub[k - i] = k;
}
list.add(sub);
}
i++;
}
return list.toArray(new int[0][]);
}
}
// 滑动窗口
class Solution {
public int[][] findContinuousSequence(int target) {
int i = 1, j = 2, sum = 3;
List<int[]> list = new ArrayList<>();
while (i < j) {
if (sum == target) {
int[] tmp = new int[j - i + 1];
for (int k = i; k <= j; k++) {
tmp[k - i] = k;
}
list.add(tmp);
}
// 继续向后遍历
if (sum >= target) {
sum -= i;
i++;
} else {
j++;
sum += j;
}
}
return list.toArray(new int[0][]);
}
}
class Solution {
public int[][] findContinuousSequence(int target) {
//时间复杂度为O(target),因为两个指针每一个最多移动(target/2 - 1)次
//空间复杂度为O(1)
List<int[]> res = new ArrayList<>();
for (int l = 1, r = 2; l < r; ) {
//等差数列求和公式
int sum = (l + r) * (r - l + 1) / 2;
if (sum == target) {
int[] tmp = new int[r - l + 1];
for (int i = l, index = 0; i <= r; i ++) {
tmp[index ++] = i;
}
res.add(tmp);
//这里直接l++,因为r++后sum一定大于target,还是执行l++
l ++;
} else if (sum > target) {
l ++;
} else if (sum < target) {
r ++;
}
}
return res.toArray(new int[res.size()][]);
}
}
class Solution {
public int[][] findContinuousSequence(int target) {
if (target == 1 || target == 2) {
return new int[0][0];
}
List list = new ArrayList<>();
int window = (int)Math.sqrt(2 * target); // 序列长度上限
for (int i = window; i > 1; i--) {
int[] res = new int[i];
int mid = target / i;
int value = mid - (i - 1) / 2;
int sum = (2 * value + i - 1) * i / 2;
if ( sum != target) {
continue;
}
for (int j = 0; j < i; j++, value++) {
res[j] = value;
}
list.add(res);
}
return list.toArray(new int[list.size()][]);
}
}
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
// a1 = (Sn - n(n - 1) / 2 ) / n
vector<vector<int>> resVec;
for (int n = sqrt(target * 2); n > 1; n--) {
long tmp = target - n * (n - 1) / 2;
if (tmp % n != 0) continue;
int a1 = tmp / n;
if (a1 <= 0) continue;
vector<int> vec(n);
for (int i = 0; i < n; i++) {
vec[i] = a1++;
}
resVec.push_back(vec);
}
return resVec;
}
};
滑动窗口法
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>> resVec;
int i = 1;
int j = 1;
int sum = 1;
while (i <= target / 2) {
if (sum < target) {
j++;
sum += j;
} else if (sum > target) {
sum -= i;
i++;
} else {
vector<int> vec(j - i + 1);
int tmp = i;
for (int k = 0; k < vec.size(); k++) {
vec[k] = tmp++;
}
resVec.emplace_back(vec);
sum -= i;
i++;
j++;
sum += j;
}
}
return resVec;
}
};
共以下 7 个回答
最大的序列长度不超过2*target开根号,由于是一个等差数列以及相加等于target,可以快速算出数列的第一项以及总和
时间复杂度O(n);空间复杂度O(n)
通过通项公式:Sn=na1+n(n-1)d/2,求出a1: a1 = (Sn – n(n – 1)d / 2 ) / n,再根据n构建符合要求的数列
滑动窗口法