题解 | #和为S的连续正数序列#
和为S的连续正数序列
http://www.nowcoder.com/practice/c451a3fd84b64cb19485dad758a55ebe
O(N) 双指针操作,因为是连续正数序列,所以可以有一个循环变量curSum来计算左右指针所夹的和(左闭右闭),并且一直迭代变化。
举例,1,2,3,4,5,6 sum = 9,left = 1, rigth = 3时 curSum = 6 < sum, 所以 right++, 更新之后,left = 1, right = 4, curSum = 10 > sum,所以left++, 再次更新,left = 2, right = 4, cursum = 9 == sum, 记录结果,left++
时间复杂度,left,right指针每次循环,一定有一个往前走一步,所以 次数 < 2 * n,记录所以的结果时,次数 < n,综上,< 3*n,故时间复杂度为O(N)
**此题暴力解法,可以利用等差数列的求和公式a1n + n(n-1)d/2 = sum, d == 1,从a1 = 1开始遍历,相当于求一个一元二次方程组,用求根公式,判断是否有正整数解,若有,则可以记录结果,若没有,继续遍历,
import java.util.*;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer> > res = new ArrayList<>();
int left = 1;
int right = 1;
int curSum = 1;
while(left <= right && right < sum){//左闭右闭
if(curSum == sum){
ArrayList<Integer> tmp = new ArrayList<>();
for(int i = left; i <= right; i++){
tmp.add(i);
}
res.add(tmp);
curSum -= left++;
}else if(curSum < sum){
curSum += ++right;
}else{
curSum -= left++;
}
}
return res;
}
}