计算和为给定数的连续正整数数列

 比如 sn = 100 时,总和为100 的连续正整数数列有
1 100
2 18 19 20 21 22
3 9 10 11 12 13 14 15 16

对于这种算法的设计,我们最容易想到的就是从 1 到 sn 循环遍历所有的数,对于每个数再循环计算是否以这个数为起点总和正好是sn。这种算法的时间复杂度大概是O(n*log2n), 也就是说如果这样计算,当 sn = 100万时,大概需要循环 2000万次左右。 这样做效率自然是比较低的。那么我们有没有比上述方法更高效的方法呢?答案是肯定的。

首先我们看等差数列求和的公式:Sn=n(a1+an)/2=na1+n(n-1)/2

从这个公式我们不难看出当 Sn 和 n 固定时求a1 是一个线性函数:a1 = (Sn – n(n-1)/2) / n

有了这个函数,优化这个算法就很简单了,我们只要把 n 从 1 开始遍历,一直遍历到 (Sn – n(n-1)/2) < n 为止,就可以找到所有的符合条件的连续数列了,这个算法的算法复杂度为 2N 的平方根,也就是说当 Sn = 100 万时,只需要循环1414次就可以得到所有的数列。

题目:在1~500这500个整数中,找出连续相加等于500的数?

简要分析:int[] X={1,2,i,…………499}

条件是:i+(i+1)+ ……+(i+k)=500 (1式)

运用等差数列求和公式:(k+1)*i+(k+1)*k/2=500 (2式)

其中i和k还有一个隐藏关系i*k<500 (3式)

于是很自然得到如下解法:

<?php 
$sum = 500;
$max = 500;
for ($i = 1; $i <= $max; ++$i) {
$s = ($sum - $i*($i-1)/2);
$h = $s / $i;
if ($s % $i == 0 && $s > 0 && ($h + $i - 1) <= $max) {
for ($j = 0; $j < $i; ++$j) {
echo $h++ . ';';
}
echo '<br>';
}
}
?>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值