剑指offer——和为S的连续正数序列
问题描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
思路分析
1.先判断输入数的大小,若小于3,显然没有连续的正数序列符合条件,返回输入的list.
2.此处运用公差为1的等差数列求和公式解题。
S
=
(
a
1
+
a
n
)
∗
n
2
S=\frac{(a_{1}+a_{n})*n}{2}
S=2(a1+an)∗n其中,
n
=
a
n
−
a
1
+
1
n={a_{n}-a_{1}+1}
n=an−a1+1 所以,可得
2
S
=
(
a
1
+
a
n
)
∗
(
a
n
−
a
1
+
1
)
2S=(a_{1}+a_{n})*({a_{n}-a_{1}+1} )
2S=(a1+an)∗(an−a1+1)
如:输入和S=15.
从a1=1开始找,显然,首项a1要小于S/2+1,即a1<8,如果a1=8,往后找8+9>15。
根据公式判断条件,
当a1=1,
2*15=(1+an)*(an-1+1),解得an=5。
把a1到an存入序列temp,再把temp存入list。即此时输出[[1,2,3,4,5]]
当a1=2,3均不满足条件
当a1=4,解得an=6。
此时输出[[1,2,3,4,5],[4,5,6]]
同理,最终输出[[1,2,3,4,5],[4,5,6],[7,8]]
代码
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
if (sum < 3) {
return list;
}
int a1;
int an;
int n;
int S = sum;
for (a1 = 1; a1 < S / 2 + 1; a1++) {
for (an = a1 + 1; an < S; an++) {
if ((a1 + an) > S)
break;
n = an - a1 + 1;
if ((a1 + an) * n == 2 * S) {
ArrayList<Integer> temp = new ArrayList<>();
for (int i = a1; i <= an; i++) {
temp.add(i);
}
list.add(temp);
break;
}
}
}
return list;
}
}