您的位置:首页 > 其它

寻找和为定值的两个数

2014-07-24 15:49 309 查看
题目:输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数

字。

要求时间复杂度是 O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。

例如输入数组 1、2、4、7、11、15 和数字 15。由于 4+11=15,因此输出 4 和 11。

分析:

1、最简答的方法就是穷举法,挨个计算比较,时间复杂度为O(N^2)

2、每一次要查找的时间都要花费为 O(N),这样下来,最终找到两个数还是需要 O(N^2)的复杂度。利用二分查找,可以将 O(N)的查找时间提高到O(log2N)

3、双指针扫描法

两个指针 i,j,各自指向数组的首尾两端, 令i=0, j=n-1, 然后i++, j--,逐次判断a[i]+a[j]?=sum, 如果某一刻a[i]+a[j]>sum,则要想办法让 sum 的值减小,所以此刻 i 不动,j--,如果某一刻 a[i]+a[j]<sum,则要想办法让 sum 的值增大,所以此刻 i++,j 不动。时间复杂度为O(N)

//输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。
//要求时间复杂度是 O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。
//例如输入数组 1、2、4、7、11、15 和数字 15。由于 4+11=15,因此输出 4 和 11
#include <iostream>
using namespace std;

//直接穷举法
void find1(int a[],int n,int sum)
{
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if(a[i]+a[j]==sum)
{
cout<<a[i]<<'+'<<a[j]<<'='<<a[i]+a[j]<<endl;
return;
}
}
}
}
//头尾双指针扫描法 O(n)
void find2(int a[],int n,int sum)
{
int f=0,b=n-1;
while(f<b)
{
if(a[f]+a[b]<sum)
f++;
else if(a[f]+a[b]>sum)
b--;
else
{
cout<<a[f]<<'+'<<a[b]<<'='<<a[f]+a[b]<<endl;
return;
}
}
}
//二分查找法 O(nlog2n)
int search(int a[], int n, int v)
{
int f=0,b=n-1;
int mid=f+(b-f)/2;
while(f<b)
{
mid=f+(b-f)/2;
if(a[mid]==v)
return mid;
else if(a[mid]<v)
f=mid+1;
else
b=mid-1;
}
return -1;
}
void find3(int a[],int n,int sum)
{
for(int i=0;i<n;i++)
{
int v=sum-a[i];
int j=search(a,n,v);//二分查找加快速度
if(j>0)
{
cout<<a[i]<<'+'<<a[j]<<'='<<a[i]+a[j]<<endl;
return;
}

}
}
void main()
{

int a[]={1,2,4,7,11,15};
int n=sizeof(a)/sizeof(int);
find1(a,n,15);
find2(a,n,15);
find3(a,n,15);
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: