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

来源:互联网 发布:java replace$ 编辑:程序博客网 时间:2024/05/22 05:08

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


算法思路:设置两个指针,s1指向数组的起始位置,s2指向数组的结束位置,然后将它们指向的值相加,如果大于s,说明大的数字太大,s2向前移动一位再次判断,如果小于s,s1向后移动移动,直到找出和为s的两个数字。


例如:{1,2,4,7,11,15}找出和为15的两个数字

1.s1指向1,s2指向15,1+15=16>15所以s2向前移

2.1+11<=12<15,s1向后移一位

3.2+11=13<15,s1向后移一位

4.4+11=15=15,结束


#include <iostream>using namespace std;bool FindNumbersWithSum(int data[],int length,int sum,int * num1,int * num2){bool found=false;if(length<1||data==NULL||num1==NULL||num2==NULL){return found;}int start=0;int end=length-1;while(start<end){int currentSum=data[start]+data[end];if(currentSum==sum){found=true;*num1=data[start];*num2=data[end];break;}else if(currentSum>sum){end--;}else{start++;}}return found;}int main(){int data[]={1,2,4,7,11,15};int num1=0;int num2=0;bool found=FindNumbersWithSum(data,6,15,&num1,&num2);if(found){cout<<num1<<endl;cout<<num2<<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的值,如果小于s,增大big的值。


例如:正数序列 1,2,3,4,5,6,7,8,输出所有和为15的序列

1.small指向1,big指向2,1+2=3<15,big++指向3

2.1+2+3=6<15,big++,指向4

3.1+2+3+4=10<15,big++

4.1+2+3+4+5=15,输出当前small到big的序列big++

5.1+2+3+4+5+6=21>15,small++指向2

6.2+3+4+5+6=20>15,small++

7.3+4+5+6=18>15,small++

8.4+5+6=15,输出当前small到big的序列4 5 6,big++

......


#include <iostream>using namespace std;void PrintSequence(int small,int big){for(int i=small;i<=big;i++){printf("%d ",i);}printf("\n");}void FindSequence(int sum){if(sum<3){return;}int small=1;int big=2;int currentSum=small+big;//因为至少含有两个数,而且序列递增所以一直增加small到mid为止int mid=(sum+1)/2;while(small<mid){if(currentSum==sum){//输出序列PrintSequence(small,big);big++;currentSum+=big;}else if(currentSum<sum){big++;currentSum+=big;//加上增大后的值}else{currentSum-=small;//减去当前序列中最小的值small++;}}}int main(){FindSequence(15);return 0;}



0 0
原创粉丝点击