题目描述:
6 15
1 2 4 7 11 15
4 11
思路:这一道题目很简单, 其中最直接的做法是暴力破解法,用两个for循环,时间复杂度为O(n*n),但是这样没有充分利用升序数组这一前提,并且效率极低。
可以用类似于二分查找的方法来求,假设数组为A,长度为len,给定的和为sum,最好的方法是先用数组的第一个数A[low]和最后一个数A[high]相加,看是否等于sum,如果等于sum,则找到了一组数,返回true,如果大于sum,则将较大的数向前移动一位,即high--,此时变成了第一个和倒数第二个数相加,如果小于sum,则将较小的数向后移动一位,即low++,此时变成了第二个和最后一个数相加,依此类推,如果low==high时还未找到和为sum的一组数,则返回false。该算法的时间复杂度为O(n),空间复杂度为O(1)。
实现代码如下:
<span style="font-size:18px;">// offer01.cpp : 定义控制台应用程序的入口点。
//
#include "stdio.h"
//在升序数组A中找出和为sum的任意两个元素,并且保存在a和b中
bool FindNumSum(int *A,int len,int sum,int *a,int *b)
{
if(A==NULL||len<2||A[0]>sum)
return false;
int low=0;
int high=len-1;
while(low<high)
{
if(A[low]+A[high]==sum)
{
*a=A[low];
*b=A[high];
return true;
}
else if(A[low]+A[high]<sum)
low++;
else
high--;
}
return false;
}
//main 函数
int main()
{
int n,k;
static int A[1000000];
while(scanf("%d %d",&n,&k)!=EOF)
{
int i;
for(i=0;i<n;i++)
{
scanf("%d ",A+i);
}
int a,b;
bool isFind=FindNumSum(A,n,k,&a,&b);
if(isFind)
printf("%d %d\n",a,b);
else
printf("-1 -1\n");
}
return 0;
}
</span>当a+b = c时,ab<=(a+b)^2/4,当且仅当a==b时,ab取得最大值,二者相差越远,乘积越小。
原文地址:http://blog.csdn.net/u013476464/article/details/40651451