找出和爲某個常數的數對

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;
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章