剑指offer——和为S的连续正数序列
笨方法:从1开始向后遍历,同时记下当前数组中的和,若和为sum,则将当前数组的值存入结果集中res.add(s),此时要重新 s = new ArrayList<>(),
不然后面改变 s 之后,res中的结果也会发生变化。
同时用一个下标记录下当前遍历的数组中的最小值,在 s new之后,重新拷贝过去。
也可以换一种思路,就是将此时的结果写作一个方法,每次都重新调用。
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
if(sum == 0 || sum == 1 || sum == 2) return res;
ArrayList<Integer> s = new ArrayList<>();
int listSum = 0;
int i = 1;
int low = 1;
while(i < sum){
if(listSum < sum){
listSum += i;
s.add(i++);
}
if(listSum >= sum){
if(listSum == sum){
res.add(s);
s = new ArrayList<>( );
for(int j = low; j < i; j++){
s.add( j );
}
}
listSum -= s.get(0);
s.remove(0);
low++;
}
}
return res;
}
}
别人的方法:因为是连续正整数,所以可以利用等差数列的求和公式来计算ss
同时,有高位和低位两个指针,指向连续正整数的高低位,ss == sum时,就将其数组加入到res结果集中,当ss<sum时,高位指针++,当ss> sum时,低位指针++
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
if(sum == 0 || sum == 1 || sum == 2) return res;
int left = 1;
int right = 2;
while(right < sum && left < right){
int s = ((right + left) * (right - left + 1)) >> 1;
if(s == sum){
int temp = left;
ArrayList<Integer> r = new ArrayList<>();
while(temp <= right){
r.add(temp++);
}
res.add(r);
left++;
} else if(s < sum){
right++;
} else{
left++;
}
}
return res;
}
}

浙公网安备 33010602011771号