题目:
输入一个已经按升序排序过的数组和一个数字,
在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。
分析:
因为只需要输出满足要求的一对数字即可,这里可以设置两个指针,分别指向数组头和尾,然后进行判断。假设数组为a,头指针为h,尾指针为t,输入的和为M,则有下面这几种情况:
1、若a[h]+a[t]==M, 则a[h]和a[t]即为满足条件的一对数。
2、若a[h]+a[t]< M, 说明应该增加两个数的和,则头指针后移。
3、若a[h]+a[t]> M, 说明应该减小两个数的和,则尾指针前移。
这个while循环退出的条件为:找到满足条件的一对数或者h>=t。
这种思路也是原文作者的思路,这个题的想法和之前的“和为N连续正数序列”这题的一种解法相似。
代码:
#include <stdio.h>
int a[100],M; //a数组存放数组数字,M为查询的数字
void Input(int n); //输入含n个数的数组
void GetPair(int n); //获取和为n的元素对
int main()
{
int n;
printf("Please input the number of digits: ");
scanf("%d",&n);
Input(n);
printf("Please input the number you want to query: ");
scanf("%d",&M);
GetPair(n);
return 0;
}
void Input(int n)
{
int i;
printf("Please input %d numbers: \n",n);
for (i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
}
void GetPair(int n)
{
int head,tail;
head=0;tail=n-1;
while (head<tail)
{
if (a[head]+a[tail]==M)
{
printf("Congratulations! The two numbers are: %d and %d \n",a[head],a[tail]);
return;
}
else if (a[head]+a[tail]<M)
{
head++;
}
else
{
tail--;
}
}
printf("Sorry,the two numbers dont't exist!\n");
}
扩展:如果输入的数组是没有排序的,但知道里面数字的范围,其他条件不变,如和在O(n)时间里找到这两个数字?
参考:
http://blog.csdn.net/xianliti/article/details/5695995
http://zhedahht.blog.163.com/blog/static/2541117420072143251809/