问题
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
思想
采用双指针。
- 由于一开始并不知道数组的大小,所以先不初始化,利用LinkedList记录所有可能的情况,以start,end,start,end…的形式存储。数组的长度即为lis.size()/2。
- 用sum记录当前start到end的和,不用每次都重新加和。也可以利用等差数列不采用循环直接计算sum。这里sum和target大小分为三种情况:
1)sum等于target
2)sum大于target,如果sum-end小于target,那么以当前start开头找不到符合条件的连续正整数序列,因此start+1;否则应继续减小end。
3)sum小于target,增加end。
代码
class Solution {
public int[][] findContinuousSequence(int target) {
int res[][];
if(target==1) {
res = new int[1][];
return res;
}
int start=1;
int end=1;
LinkedList<Integer> list = new LinkedList<Integer>();
int sum = start;
while(true) {
if(sum<target) {
end++;
sum=sum+end;
} else if(sum>target){
if((sum-end)>=target) {
end--;
sum = sum-end;
} else {
start++;
end--;
sum = sum-start-end;
//continue;
}
} else {
if(start==end) {
break;
}
list.add(start);
list.add(end);
sum = sum-start;
start++;
}
if(start>target) {
break;
}
}
res = new int[list.size()/2][];
return this.getRes(list,res);
}
public int[][] getRes(LinkedList list , int[][] res ) {
ArrayList<Integer> tmp = new ArrayList<>();
int len = list.size()/2;
for(int time=0 ; time<len ; time++) {
int start = (int)list.remove(0);
int end = (int)list.remove(0);
res[time] = new int[end-start+1];
res[time][0] = start;
for(int i=1 ; i<res[time].length ; i++) {
res[time][i]=res[time][i-1]+1;
}
}
return res;
}
}