1.题目:输入一个递增排序的数组和数字S,在数组中找到两个数字使他们的和为S,如果存在多对数字的和为S,则输出其中的一对即可。
分析:
例如对于数组{1,2,4,7,11,15},以及要找的和为S,我们可以设置两个指针,第一个指针指向的是数组的起始位置的值1,第二个指针指向的是末尾的数字15,计算两个指针指向的数字的和,为16,判断与S的大小关系,如果等于S,则刚好找到,如果比S小,则前面的指针向前移动一个位置,如果比S大,则后面的指针往前移动一个位置。因为是递增的序列,最后一个指针的额位置已经不能继续往后移动,前面的指针往后移动的结果就是增大两个数的和,后面的指针往前移动是缩小两个数的和。当前判断是比S大,则后面的指针往前移动,指向11,重新计算两个指针指向的数的和为12,小于15,则此时前面的额指针往前移动指向2,重新计算两个数的和为13,小于15,前面的指针继续向前移动,此时指向4,计算两个数的和为15,刚好等于15,则4和11即是我们要找的符合条件的两个数。
连续数字的情况
2.题目,输入一个正数S,打印出所有和为S的连续整数序列(至少还有两个数).例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出三个连续的序列1-5,4-6,7-8.
分析:
可以采用上面的类似的解法,用small和big分别指向起始较小的数和最后结束最大的数。计算small到big的之间的数的和,如果和比S大,则应该丢弃当前较小的small值,如果比S小,则应该增加big的值,如果等于S,那最好。
例如分析和为9的连续整数序列,small和big的初始值分别为1和2,则初始的和为3,比9小,增大big为3,和为6小于9,继续增大big,何为10大于9,则此时丢掉small,small为2,此时和刚好为9,打印出small和big之间的数2,3,4.继续增大big,发现2-5之间的和为14,大于9,丢掉此时的small,3-5之间的值为12,比9大,继续丢点此时的small,4-5的和为9,满足条件,打印4,5.此时由于small的值已到达9的一半左右,后续再无可能有满足条件的数字。结束
源码:
/**
* 功能说明:找到和为S的数字
* 作者:K0713
* 日期:2016-9-25
**/
#include<iostream>
using namespace std;
bool FindTwoNumberOfS(int *a, int length, int S, int* number1, int* number2)
{
bool found = false;
if (length < 1 || number1 == NULL || number2 == NULL)
return found;
int head = 0;
int tail = length - 1;
int sum = 0;
while (head < tail)
{
sum = a[head] + a[tail];
if (sum == S)
{
*number1 = a[head];
*number2 = a[tail];
found = true;
break;//找到第一个就停止不找了
}
else if (sum>S)//比S大,后面的指针向前移动
{
tail--;
}
else//比S小,前面的指针向后移动
{
head++;
}
}
return found;
}
//打印连续序列
void PrintContinuousSequence(int small, int big)
{
for (int i = small; i <= big; ++i)
cout << i;
cout << endl;
}
void FindContinuousSequence(int sum)
{
if (sum < 3)
return;
int small = 1;
int big = 2;
int middle = (1 + sum) / 2;//small为中间值时已不能满足条件
int curSum = small + big;
while (small < middle)
{
if (curSum == sum)
PrintContinuousSequence(small, big);
while (curSum > sum && small < middle)//太大了要丢掉前面的small
{
curSum -= small;
small++;
if (curSum == sum)
PrintContinuousSequence(small, big);
}
big++;
curSum += big;
}
}
int main()
{
int data[] = { 1, 2, 4, 7, 11, 15 };
int num1, num2;
bool result = FindTwoNumberOfS(data, sizeof(data) / sizeof(int), 15, &num1, &num2);
cout << "------------------------------" << endl;
cout << "1.和为15的两个数字:" << endl;
if (result == true)
cout << "number1: " << num1 << " number2: " << num2 << endl;
else
cout << "none" << endl;
cout << "------------------------------" << endl;
cout << "2.和为15的连续正数序列:" << endl;
FindContinuousSequence(15);
system("PAUSE");
return 0;
}
连续数字的情况
2.题目,输入一个正数S,打印出所有和为S的连续整数序列(至少还有两个数).例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出三个连续的序列1-5,4-6,7-8.
分析:
可以采用上面的类似的解法,用small和big分别指向起始较小的数和最后结束最大的数。计算small到big的之间的数的和,如果和比S大,则应该丢弃当前较小的small值,如果比S小,则应该增加big的值,如果等于S,那最好。
例如分析和为9的连续整数序列,small和big的初始值分别为1和2,则初始的和为3,比9小,增大big为3,和为6小于9,继续增大big,何为10大于9,则此时丢掉small,small为2,此时和刚好为9,打印出small和big之间的数2,3,4.继续增大big,发现2-5之间的和为14,大于9,丢掉此时的small,3-5之间的值为12,比9大,继续丢点此时的small,4-5的和为9,满足条件,打印4,5.此时由于small的值已到达9的一半左右,后续再无可能有满足条件的数字。结束
本文介绍两种算法:一种是在有序数组中找到两数之和为指定值的方法;另一种是找出所有连续整数序列,使其和为给定值。
176万+

被折叠的 条评论
为什么被折叠?



