修改了一下书上的代码,自己想了个新的解决办法
#include <iostream>
#include <ctime>
using namespace std;
//剑指Offer——输入正整数S,打印出所有和为S的连续正数序列(至少含有两个正数)
//1 2 3 4 5 = 4 5 6 = 7 8 = 15
/*剑指offer上的解法,感觉书上代码不完美,自己修改了一下*/
void print(int min,int max,int sum)
{
while(min <= max)
cout<<min++<<" ";
cout<<endl;
}
void FindContinuousSequence(int sum)
{
if(sum < 2 || sum > 0x7fffffff)
return;
int min = 1,max = 2,mid = sum / 2 + 1;//mid = (sum + 1) / 2 书上这样写有bug 当输入0x7fffffff的时候就会溢出
int curSum = min + max;
while(min < mid)
{
if(curSum == sum)
print(min,max,sum);
else if(curSum > sum)
{
curSum -= min;
min++;
continue;
}
max++;
curSum += max;
}
}
////////////////////////////自己思路////////////////////////////////////////////
void print2(int min,int max,int sum)
{
int s = 0;
for(int i = min;i <= max; i++)
s += i;
if(s == sum)
{
while(min <= max)
cout<<min++<<" ";
cout<<endl;
}
}
void FindContinuousSequence2(int sum)
{
int count = 1,mid,min;
do
{
mid = sum / ++count;
min = mid - (count - 1) / 2;
print2(min,min + count - 1,sum);
}while(min > 0);
}
void test1(int a)
{
struct timeb startTime , endTime;
ftime(&startTime);
FindContinuousSequence(a);
ftime(&endTime);
cout << "test1耗时:" << (endTime.time-startTime.time)*1000 + (endTime.millitm - startTime.millitm) << "毫秒" << endl;
}
void test2(int a)
{
struct timeb startTime , endTime;
ftime(&startTime);
FindContinuousSequence2(a);
ftime(&endTime);
cout << "test2耗时:" << (endTime.time-startTime.time)*1000 + (endTime.millitm - startTime.millitm) << "毫秒" << endl;
}
int main()
{
int a = 0x7ffff;
test1(a);
test2(a);
}
自己的思路,和二分查找思路雷同,所以效率上会高一点
现在说一下我的思路:
2个连续数相加要和sum相等肯定是sum中间的两个数啊(所以我用了sum/2),3个数加起来要和sum相等肯定是sum/3前后的数啦。
其实就是二分查找啦,算是个技巧吧