1. 程式人生 > >求兩個有序整型陣列的交集

求兩個有序整型陣列的交集

1. 問題描述

  有兩個有序的整型陣列a和b(沒有重複元素),他們的長度分別為lenA和lenB,求出他們的共同元素。
  例如:a = 0,1,3,5,7,9,11;b = 2,3,4,7,11;
  它們的交集為{3,7,11}。

2. 方法思路

  求交集的方法有很多種,但陣列的長度會影響演算法的效率。

2.1 長度相當時,可採取的演算法

2.1.1 二路歸併

  對於陣列a,b分別以i,j從頭遍歷陣列。如果當前位置的a[i]等於b[j],則這兩個數是兩個陣列的一個交集,記錄下來並繼續遍歷;如果a[i]大於b[j],則繼續遍歷陣列b,否則遍歷陣列a。程式碼如下:
  

//二路歸併法
int ComNun_Merge(int a[],int lenA,int b[],int lenB,int *comlst)
{
    int i=0,j=0,k=0;

    while(i < lenA && j < lenB)
    {
        if(a[i] == b[j] )
        {
            comlst[k++] = a[i];
            i++;
            j++;
        }
        else if(a[i] > b[j])
        {
            j++;
        }
        else
i++; } return k; }

2.1.2 雜湊查詢

  迴圈遍歷其中的一個數組,並將元素存放到雜湊表中,然後遍歷另一個數組,並進行hash查詢。如果存在,則是兩個陣列的一個交集,記錄下來,繼續查詢直到結束。
  

//雜湊表查詢法,此方法可無序,但要求元素為正數
int ComNum_Hash(int a[],int lenA,int b[],int lenB,int *comlst)
{
    int hashTb[MAX_INT] = {0},i,j,k=0;

    for(i = 0; i < lenA; i++)
        hashTb[a[i]] = 1
; for(j = 0; j < lenB; j++) { if(hashTb[b[j]] == 1) comlst[k++] = b[j]; } return k; }

2.2 兩陣列長度相差較大

  在這種情況下,可以考慮使用二分查詢法。先遍歷長度較小的陣列,然後將這個元素值在在長度較大的陣列中進行二分查詢。
  

//二分查詢法
int ComNum_Binary(int a[],int lenA,int b[],int lenB,int *comlst)
{
    int i,j,k=0;

    for(i = 0; i < lenA; i++)
    {
        int l=0,r=lenB-1,mid;

        while(l <= r)
        {
            mid = (l+r)/2;

            if( a[i] < b[mid] )
                r = mid -1;
            else if( a[i] > b[mid] )
                l = mid +1;
            else
            {
                comlst[k++] = a[i];
                break;
            }
        }
    }
    return k;
}