剑指Offer_#57-II_和为 s 的连续正数序列
Contents
题目

解答
方法1: 滑动窗口
class Solution {
List<int[]> list= new ArrayList<>();
public int[][] findContinuousSequence(int target) {
int small = 1;
int big = 2;
//(target + 1) / 2是target的一半(偶数)或target一半的上取整(奇数)
//small应该小于mid,否则连续的两个数必定超过target
int mid = (target + 1) / 2;
int curSum = small + big;
//small不能超过mid
while(small < mid){
if(curSum == target) printToRes(small, big);
//如果当前的和大于target,从small开始,排除多个数字,直到curSum <= target
while(curSum > target && small < mid){
curSum -= small;
small++;
if(curSum == target) printToRes(small, big);
}
//经过上面的循环,curSum <= target,所以需要增加big
big++;
curSum += big;
}
//res是一个不规则数组,只需要指定第一维的长度,第二维的长度是不固定的,无需指定
int[][] res = new int[list.size()][];
for(int i = 0;i <= res.length - 1;i++){
res[i] = list.get(i);
}
return res;
}
//将数组[small...big]添加到list中
private void printToRes(int small, int big){
int len = big - small + 1;
int[] res = new int[len];
for(int i = 0; i <= len - 1;i++){
res[i] = small++;
}
list.add(res);
}
}
复杂度分析
时间复杂度:O(target)
空间复杂度:O(1)
代码优化
class Solution {
public int[][] findContinuousSequence(int target) {
int i = 1, j = 1;
int sum = 0;
List<int[]> res = new ArrayList<>();
while(i <= target / 2){
if(sum < target){
sum += j;
j++;
}else if(sum > target){
sum -= i;
i++;
}else{
int[] arr = new int[j - i];
for(int k = i; k < j; k++) arr[k - i] = k;
res.add(arr);
sum -= i;
i++;
}
}
return res.toArray(new int[res.size()][]);
}
}