转自点击打开链接
题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,是的题目的和正好是输入的那个数字。要求时间复杂度为O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
例如输入数组[1,2,4,7,11,15]和数字15,由于4+11=15,因此输出4和11。
分析:这道题目想了一下就得出了结果,最主要的限制还是在时间复杂度为O(n),如果没有这个限制则处理起来相对容易,先将第一个元素和最后一个元素相加,如果结果比期望的结果小,则从第一个元素向后移动,因为已经按照升序排好序,所以后面的元素一定比前面的元素大,如果结果比期望的结果大,则需要相应的缩小一些值,则从最后一个元素向前移,直到碰到两数相加的和相等给定的值,或者从第一个元素开始遍历的变量大于从最后一个元素开始遍历的变量,则推出,给定的排序序列中不包含这样的两个数。
依然有一些问题,需要拿出来检讨一下,对于返回的两个变量,一开始我不知道该如何表示,于是就定义了一个结构体,他的两个成员变量为int,后来发现确实有些不合适,原文作者给的答案时,函数的输入参数里面有两个引用,从外部传入,在函数内部改变他的值,值的借鉴。对于函数的返回值则设置成一个bool型变量,当成功找到时为true,找不到是false。函数的参数中有一个表示数组长度的值 length,将他的类型设置为int型没有错误,照样可以跑,不过似乎有点逻辑上的不严谨,其实我们可以想明白,实际中的长度是没有负数的,所以应该设置为unsigned int,对于输入的length,需要在函数内部判断一下他是否符合条件 ,如果为负数,则直接的返回退出。
我的代码如下:
1 #include <iostream> 2 using namespace std; 3 bool FindTotalSumElements(int inputArray[],int sum,unsigned int length, int &mfront, int &mrear) 4 { 5 bool isFind=false; 6 if(length < 0) 7 return isFind; 8 int front,rear; 9 front=0; 10 rear=length-1; 11 while(front<rear) 12 { 13 int curSum= inputArray[front] + inputArray[rear]; 14 if(curSum == sum) 15 { 16 mfront = inputArray[front]; 17 mrear = inputArray[rear]; 18 isFind = true; 19 break; 20 } 21 if(curSum < sum) 22 front++; 23 if(curSum > sum) 24 rear--; 25 } 26 return isFind; 27 } 28 void main() 29 { 30 int element1,element2; 31 int array[] = {2,4,6,8,10}; 32 int len = sizeof(array) / sizeof( int ); 33 if(FindTotalSumElements(array, 14, len,element1,element2)) 34 { 35 cout<<element1<<endl; 36 cout<<element2<<endl; 37 } 38 else 39 cout<<"can not find the two elements"<<endl; 40 }