您的位置:首页 > Web前端

剑指Offer学习总结-和为S的连续正数序列

2018-01-25 13:04 323 查看

剑指Offer学习总结-和为S的连续正数序列

本系列为剑指Offer学习总结,主要是代码案例的分析和实现:

书籍链接:http://product.dangdang.com/24242724.html

原作者博客:http://zhedahht.blog.163.com/blog/static/254111742011101624433132/

原作者博客链接有完整的项目代码下载。

和为S的连续正数序列

题目

题目:输入一个正数S,打印出所有和为S的连续正数序列(至少有两个数)。

例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5,4~6和7~8.

最初的解法

暴力解法,直接按元素开始位置,先固定开始元素,然后挨个累加后边的元素,直到累加和大于等于和S,

然后开头元素右移,重新开始累加。

开头元素直到等于和S。

双指针的解法

有了前边上一个题目的思路,我们同样可以模仿一下。这里的数组大小就是从1到和为S-1的内容。

依然使用两个数small和big分别表示序列的最小值和最大值。

首先把small初始化为1,big初始化为2,如果从small到big的值的和大于s,从序列中去掉较小的值,也就是增大small的值,如果小于s,增大big的值。

求和为9的所有连续序列

我们先把 small 初 始 化 为 1 , big 初始化为 2。

此时介于 small 和 big 之间的序列是{1,2}, 序列的和为 3, 小于9, 所以我们下一步要让序列包含更多的数字。

我们把 big 增 加 1 变 成 3,此 时 序 列 为{1,2,3} ,由于序列的和是6, 仍然小于9,

我们接下来再增加big变成4, small 和 big 之间的序列也随之变成 {1,2,3,4}, 由于序列和变成10大于9,

我们要删除序列中的一些元素,于是smamll变成2,

此时得到的序列是{2,3,4},序列和正好是9。我们找到了第一个结果。

接下来我们继续增加big,重复之前的操作。



void FindContinuousSequence(int sum)
{
if(sum < 3)
return;

int small = 1; //序列的开头
int big = 2;    //序列的结束
int middle = (1 + sum) / 2;
int curSum = small + big;

//两个连续的数字 符合条件的最大可能就是 和的一半前后的数值  比如5  最大是 2 3
while(small < middle)
{
//考虑当前序列和 与 最终要求结果的对比Sum
if(curSum == sum)
PrintContinuousSequence(small, big);

while(curSum > sum && small < middle)
{
curSum -= small;
small ++;

if(curSum == sum)
PrintContinuousSequence(small, big);
}

big ++;
curSum += big;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: