题目:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。

例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。

思路整理一下:最初我们找到数组的第一个数字和最后一个数字。首先定义两个指针,第一个指针指向数组的第一个(也就是最小的)数字,第二个指针指向数组的最后一个(也就是最大的)数字。当两个数字的和大于输入的数字时,把较大的数字往前移动;当两个数字的和小于数字时,把较小的数字往后移动;当相等时,打完收工。这样扫描的顺序是从数组的两端向数组的中间扫描。

bool FindNumbersWithSum(int data[], int length, int sum, int *num1, int *num2)
{
bool found = false;
if(length < 1 || num1 == NULL || num2 == NULL)
return false; int ahead = length - 1;
int behind = 0; while(ahead > behind)
{
long long curSum = data[ahead] + data[behind];
if(curSum == sum)
{
*num1 = data[behind];
*num2 = data[ahead];
found = true;
break;
}
else if(curSum > sum)
ahead--;
else
behind++;
}
return found;
}

测试代码:

#include<iostream>
using namespace std; bool FindNumbersWithSum(int data[], int length, int sum, int *num1, int *num2)
{
bool found = false;
if(length < 1 || num1 == NULL || num2 == NULL)
return false; int ahead = length - 1;
int behind = 0; while(ahead > behind)
{
long long curSum = data[ahead] + data[behind];
if(curSum == sum)
{
*num1 = data[behind];
*num2 = data[ahead];
found = true;
break;
}
else if(curSum > sum)
ahead--;
else
behind++;
}
return found;
} int main()
{
int data[] = {1, 2, 4, 7, 11, 15};
int length = sizeof(data) / sizeof(int); int num1, num2;
bool result = FindNumbersWithSum(data, length, 15, &num1, &num2);
if(result)
{
cout<<"num1:"<<num1<<endl;
cout<<"num2:"<<num2<<endl;
}
else
cout<<"failed!"<<endl; return 0;
}

题目:输入一个正数S,打印出所有和为S的连续正数序列(至少有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5,4~6和7~8.

有了解决前面问题的经验,这里也考虑两个数small和big分别表示序列的最小值和最大值。

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

如果从small到big的序列的和小于S,可以增大big,让这个序列包含更多的数字。因为这个序列至少要有两个数字,我们一直增加small到(1+S)/2为止。

void FindContinuousSequence(int sum)
{
if(sum < 3)
return; int small = 1;
int big = 2;
int middle = (1 + sum) / 2;
int curSum = small + big; while(small < middle)
{
if(curSum == sum)
PrintContinuousSequence(small, big); while(curSum > sum && small < middle)
{
curSum -= small;
small++; if(curSum == sum)
PrintContinuousSequence(small, big);
} big++;
curSum += big; }
} void PrintContinuousSequence(int small, int big)
{
for(int i = small; i <= big; ++i)
printf("%d ", i);
printf("\n");
}

扩展:

2010年中兴面试题
编程求解:
输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来。

#include<list>
#include<iostream>
using namespace std; list<int>list1;
void find_factor(int sum, int n)
{
// 递归出口
if(n <= 0 || sum <= 0)
return; // 输出找到的结果
if(sum == n)
{
// 反转list
list1.reverse();
for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)
cout << *iter << " + ";
cout << n << endl;
list1.reverse();
} list1.push_front(n); //典型的01背包问题
find_factor(sum-n, n-1); //放n,n-1个数填满sum-n
list1.pop_front();
find_factor(sum, n-1); //不放n,n-1个数填满sum
} int main()
{
int sum, n;
cout << "请输入你要等于多少的数值sum:" << endl;
cin >> sum;
cout << "请输入你要从1.....n数列中取值的n:" << endl;
cin >> n;
cout << "所有可能的序列,如下:" << endl;
find_factor(sum,n);
return 0;
}

和为S的两个数字VS和为s的连续正数序列的更多相关文章

  1. 【面试题041】和为s的两个数字VS和为s的连续正数序列

    [面试题041]和为s的两个数字VS和为s的连续正数序列 题目一:     输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和等于s,输出任意一对即可. ...

  2. [剑指Offer]41.和为S的两个数字 VS 和为S的连续正数序列

    [剑指Offer]41 和为S的两个数字 VS 和为S的连续正数序列 Leetcode T1 Two Sum Given an array of integers, return indices of ...

  3. 【剑指offer】面试题41:和为 s 的两个数字 VS 和为 s 的连续正数序列

    题目: 输出所有和为S的连续正数序列.序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序 思路: small代表序列最小数字,large代表序列最大数字.初始化small为1,large为2. ...

  4. 和为 s 的两个数字(和为 s 的连续正数序列)

    题目 输入一个递增排序的数组和一个数字 s,在数组中查找两个数,得它们的和正好是 s.如果有多对数字的和等于 s,输出任意一对即可 思路 我们先在数组中选择两个数字,如果它们的和等于输入的 s,我们就 ...

  5. 面试题41:和为s的两个数字VS和为s的连续正数序列

    题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和为s,输出任意一对即可. vector<int> findNumberwWithSu ...

  6. 剑指offer——和为s的两个数字VS和为s的连续正数序列

    两种方法都类似于快排的变形. #include <iostream> #include <string> using namespace std; bool FindNumbe ...

  7. 剑指offer-第六章面试中的各项能力(和为S的两个数字VS和为S的连续正序列)

    题目1:输入一个排序数组和一个值S,输出数组中两个数的和为S的任意一对数. 思路:分别用两个指针指向数组的头start和尾end.如果两个数字之和等于S输出.如果打于,则end--,再次相加.因此循环 ...

  8. 面试题41:和为s的两个数字 || 和为s的连续正数序列

    和为s的两个数字 题目:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和等于s,输出任意一对即可. 有点类似于夹逼的思想 注意两个int相加的和要用lo ...

  9. 和为s的两个数字 和为s的连续正数序列

    输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可. #include <iostream> using namesp ...

随机推荐

  1. mysql学习之-三种安装方式与版本介绍

    MYSQL版本介绍 mysql分alpha,beta,rc,GA四个版本. alpha  暗示这是一个以展示新特性为目的的版本,存在比较多的不稳定因素,还会向代码中添加新新特性beta 以后的beta ...

  2. Linq的Distinct方法的扩展

    原文地址:如何很好的使用Linq的Distinct方法 Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1&qu ...

  3. EF Power Tools

    EF Power Tools可以从数据库反向生成实体及映射文件.一般在使用EF,有Database First,Code First以及Model First.常用的是Database First和C ...

  4. @include与jsp:include的区别

    1.可以使用一个JSP指令或者一个标准行为,在JSP页面中引入其他的页面片段. 2. include指令:在翻译阶段(将JSP页面转换成servlet的阶段),JSP的include指令会读入指定的页 ...

  5. 未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项

    Win7 64位 IIS未能加载文件或程序集"System.Data.SQLite"或它的某一个依赖项 未能加载文件或程序集"System.Data.SQLite&quo ...

  6. linux服务之vnc和x2go

    三种方式连接linux桌面 1.传统的vnc linux桌面上安装vncserver windows桌面上安装vncviewer 2.x2go 在linux桌面上安装x2goserver与x2gose ...

  7. Apache ab并发负载压力测试

    由于现在网站都需要能够承受高并发要求的能力,所以当我们写完代码后,如果需要上线,最好都经过压力测试后,这样比较好 运行: 在Windows系统下,打开cmd命令行窗口,定位到apache安装目录的bi ...

  8. Deferred和Promise之间有什么区别呢?

    一个promise就是一个由异步函数返回的对象. deferred对象就是jQuery的回调函数解决方案. 总结 jQuery 的ajax 就是返回一个promise 对象,里面含有done(), f ...

  9. sklearn小知识

    特征缩放:# 为了追求机器学习和最优化算法的最佳性能,我们将特征缩放 from sklearn.preprocessing import StandardScaler sc = StandardSca ...

  10. mybatis 中的稍微复杂些的sql语句

    mybatis 中的稍微复杂些的sql语句: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYP ...