在升序数组中查找和等于给定值的两个数
来源:互联网 发布:unity3d 5.x下载 编辑:程序博客网 时间:2024/05/16 14:23
【题 目】输入一个已经按升序排列的数组,一个给定的数字,在数组中查找两个数,使得它们的和等于给定的数字。要求时间复杂度为O(n),如果存在多对满足条件的数字对,只给出一对即可。例如:输入数组『1,2,4,7,11,15』,给定一个数字15,那么输出应该为『4,11』.
【思路1】我们先不考虑时间复杂度为O(n),按照最直观的思路来考虑,容易想到,我们一次固定数组中的一个数字,然后遍历这个数字之后的各个数字,判断和是否为给定的和,这样的时间复杂度为O(n2)。容易写出如下的代码:
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 bool FindTwoNumbers(int array[],int length,int sum,int &num1,int &num2) 6 { 7 if(array == NULL || length < 2) 8 return false; 9 10 for(int i = 0;i < length - 1;++i)11 {12 for(int j = i + 1;j < length;++j)13 {14 if(array[i] + array[j] == sum)15 {16 num1 = array[i];17 num2 = array[j];18 return true;19 }20 }21 }22 23 return false;24 }25 26 int main()27 {28 cout<<"Enter the length of your array:"<<endl;29 int arraylength = 0;30 cin>>arraylength;31 int *p = new int[arraylength];32 33 cout<<"Enter the numbers in your array:"<<endl;34 for(int i = 0;i < arraylength;++i)35 {36 cin>>p[i];37 }38 39 cout<<"Enter a sum you want to find:"<<endl;40 int result = 0;41 cin>>result;42 43 int a = 0;44 int b = 0;45 FindTwoNumbers(p,arraylength,result,a,b);46 47 cout<<"the two numbers are:"48 <<"\t"<<a<<"\t"<<b<<endl;49 50 delete[] p;51 return 0;52 }
运行结果如下:
【思路2】上面的算法时间复杂度为O(n2),但是这个算法有一个好处就是,对于不排序的数组也是能够适用的,因为我们采用的方法是遍历,对于排序不排序,我们并不关心。这也从一个侧面说明了上面的算法时间复杂度较高的原因是:我们并没有充分利用数组是按升序排列的这个条件。如果考虑这个条件,我们会怎么做?
我们考虑一种特殊的情况,数组是严格的等差数列,那么给定一个和,如果能够找到一对整数满足题条件,那么根据等差数列的性质,较大的数想左移动一个数字,叫小的数向有移动一个数字,就又找到了另一对满足条件的数对。那么对于一般情况,我们能否这样考虑:首先判断第一个数字和最后一个数字的和,如果这个和大于给定的和,那么就让最后一个数字左移;反之,如果它们的和小于给定的和,就让第一个数字右移,这样是合乎逻辑的,然而这个算法容易使人产生一个疑问,会不会漏掉呢?这需要严格的数学证明,笔者暂时还不能给出证明,待日后补充,也希望数学很牛的同学不吝赐教。该思路代码如下:
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 bool FindTwoNumbers(int array[],int length,int sum,int &num1,int &num2) 5 { 6 //无效输入,返回false 7 if(array == NULL || length < 2) 8 return false; 9 10 int *start = &array[0];11 int *end = &array[length -1];12 13 while(start < end)14 {15 if((*start + *end) == sum)16 {17 num1 = *start;18 num2 = *end;19 return true;20 }21 22 //小于给定和,较小的数右移23 else if((*start + *end) < sum)24 {25 start++;26 }27 28 //大于给定和,较大的数左移29 else if((*start + *end) > sum)30 {31 end--;32 }33 }34 35 return false;36 }37 38 39 int main()40 {41 cout<<"Enter the length of your array:"<<endl;42 int arraylength = 0;43 cin>>arraylength;44 int *p = new int[arraylength];45 46 cout<<"Enter the numbers in your array:"<<endl;47 for(int i = 0;i < arraylength;++i)48 {49 cin>>p[i];50 }51 52 cout<<"Enter a sum you want to find:"<<endl;53 int result = 0;54 cin>>result;55 56 int a = 0;57 int b = 0;58 FindTwoNumbers(p,arraylength,result,a,b);59 60 cout<<"the two numbers are:"61 <<"\t"<<a<<"\t"<<b<<endl;62 63 delete[] p;64 return 0;65 }
运行结果如下:
References:
程序员面试题精选100题:http://zhedahht.blog.163.com/blog/static/2541117420072143251809/
注:
1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。
2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。
- 在升序数组中查找和等于给定值的两个数
- 在给定数组中查找两个数的和等于给定的数
- 在给定数组中查找两个数的和为给定值sum
- 一个已经按升序排序过的数组和一个数字, 在数组中查找两个数,使得它们的和正好等于输入的那个数字
- 在数组中求出两个数,使他们的和等于给定的一个数
- 给定一个数组,从中查找是否存在两个数的和等于一个给定的x
- python求解在给定递减数组中寻找两个数和等于定值,乘积最小
- 【100题】在排序数组中查找和为给定值的两个数
- 判断数组中是否存在和等于给定值的两个数
- 在排序数组中寻找两个数使其和等于给定数
- 微软,Google面试题 (10) —— 在排序数组中寻找两个数的和等于给定数
- 判断一个有序数组中是否有两个数的和等于给定的数
- 关于一个数组中两个数的和等于给定数的问题
- 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数
- 在数组中找出两个数a、b,使得a加b等于给定的c
- PHP实现数组中两个数的和等于给定的目标值
- PHP实现数组中两个数的和等于给定的目标值
- 在升序数组中查找两个数,使得它们的和正好是输入的那个数字
- 整数的转换成2进制有多少个1
- Extjs 解决乱码
- C#自定义用户浏览网页权限
- 理解栈帧
- 通信行业应届毕业生起薪【2012年新版】
- 在升序数组中查找和等于给定值的两个数
- ssh2项目例子(政府类)
- 建设项目经济评价信息化手段
- 和为n的连续正数序列
- 32位和64位的区别--深入理解计算机系统笔记一
- macvim
- Java程序员的发展前景
- CentOS6.2下一步一步源代码安装OpenStack(十)Swift测试
- VC中自画控件的过程和方法(CButton, CEdit, etc)