找出和为某个常数的数对

来源:互联网 发布:文明5黄金时代算法 编辑:程序博客网 时间:2024/05/22 01:17
1. 问题描述
已知大小分别为m,n的两个无序数组A,B和一个数常数c, 求满足A[i] + B[j] = c的所有A[i]和B[j]。


【方案一】
<枚举法> 这是最简单的方法,枚举A和B中所有元素对,看其和是否为c,如果是,则输出。


【方案二】
<排序+二分查找> 首先,对两个数组中较大数组(不妨设为A)排序;然后,对于B中每个元素B[i],

在A中二分查找c-B[i],如果找到,直接输出。 时间复杂度为:O(mlogm+nlogm)。


/*【方案三】<排序+线性扫描>该方法是方案二的进一步加强,需要对两个数组排序。首先,对A和B进行排序;然后用指针p从头扫描A,用指针q从尾扫描B,如果A[p] + B[q] == c,则输出A[p]和B[q],且p++,q--;如果A[p]+B[q]>c,则q--;否则p++。时间复杂度为:O(mlogm+nlogn)。*/void sum_pairs(int *a, int n, int *b, int m, int sum){//O(mlogm + nlogn)    sort(a, a + n);    sort(b, b + m);    int p = 0, q = m - 1;    while(p < n && q >= 0)    {        if(a[p] + b[q] == sum)        {            cout << "a[p] = " << a[p] << " b[q] = " << b[q] << endl;            p ++; q --;        }        else if(a[p] + b[q] > sum)            q --;        else            p ++;    }}

/*【方案四】<HashTable法>首先,将两个数组中较小数组(不妨设为A)保存到HashTable中,然后,对于B中每个元素B[i],也采用相同hash算法在HashTable中查找c-B[i]是否存在,如果存在,则输出。时间复杂度为:O(m+n),空间复杂度为:O(min{m,n})。*/void sum_pairs2(int *a, int n, int *b, int m, int sum){//O(m + n)  空间:O(min(n, m))    int *pSma = a, *pBig = b;    int nSma = n, nBig = m;    if(n < m)    {        pSma = b; pBig = a;        nSma = m; nBig = n;    }    set <int> hash_table;    hash_table.insert(pSma, pSma + nSma);    for(int i = 0; i < nBig; i ++)    {        if(hash_table.find(sum - pBig[i]) != hash_table.end())            cout << sum - pBig[i] << " " << pBig[i] << endl;    }}


原创粉丝点击