给定一个数组,在数组中找到满足条件的两个数,使得这两个数的和为某一给定的值。如果有多对数,只输出一对即可。
1、NC枚举,显然O(n^2)
先sort使数组变为有序:
2、满足单调性,枚举一个位置+最基础的二分查找 O(nlogn+nlogn)
//二分查找:
typedef pair<int,int> pa;
int binarySearch(int a[],int l,int r,int val)
{
while(l<r){
int mid=l+(r-l)/2;
if(a[mid]==val) return mid;
if(a[mid]>val) r=mid-1;
else l=mid+1;
}
return -1;
}
pa getsumNum(int a[],int n,int sum)
{
for(int i=1;i<=n;i++){
int pos=binarySearch(a,i+1,n,sum-a[i]);
if(pos==-1) continue;
return make_pair(i,pos);
}
return make_pair(-1,-1);
}
3、双指针法,常用于预处理 O(n+nlogn)
复杂度取决于排序
typedef pair<int,int> pa;
pa getSumNum(int a[],int n,int sum)//找不到则返回(-1,-1)
{
int i=1,j=n-1;
while(i<j){
if(a[i]+a[j]==sum) return make_pair(i,j);
else if(a[i]+a[j]<sum) i++;
else j--;
}
return make_pair(-1,-1);
}
尝试一下for循环的写法:
typedef pair<int,int> pa;
pa GetSumNum(int a[],int n,int sum)
{
for(int i=1,j=n-1;i<j;){
if(a[i]+a[j]==sum) return make_pair(i,j);
else if(a[i]+a[j]<sum) i++;
else j--;
}
return make_pair(-1,-1);
}
这一简单的思想也可用于树问题的处理:
给定一棵有根树,根为p,问有多少点对(u, v),使得u,v 距离大于等于W。
改为cnt记录即可。记得排序
评论 (0)