1. 程式人生 > >程式設計題:給定兩個集合,求兩個集合的交集

程式設計題:給定兩個集合,求兩個集合的交集

題目:給定兩個整數集合,求兩個集合的交集。

法一:排序法(先將集合排序,在找交集)

            排序時間複雜度O(nlogn),對集合遍歷查詢O(n);總的時間複雜度O(nlogn);

void main()
{
	int a[] = { 1, 5, 9, 8, 6, 4 };
	int b[] = { 9, 4, 2, 0, 5, 11, 12 };
	int alen = sizeof(a) / sizeof(int);
	int blen = sizeof(b) / sizeof(int);
	sort(a, a + alen);//排序
	sort(b, b + blen);
	vector<int> res; //儲存結果
	if (a[0] > b[blen - 1] || b[0] > a[alen - 1])
		return;
	
	int i = 0,j = 0;
	while (i < alen &&j < blen) //查詢
	{
		if (a[i]>b[j])
			j++;
		else if (a[i] < b[j])
			i++;
		else
		{
			res.push_back(a[i]);
			cout << a[i] << "  ";
			i++; j++;
		}
	}
	cout << endl;
}

  法二:點陣圖法(很巧妙啊)

時間複雜度:O(n) ,空間複雜度取決於最短陣列的最大值和最小值差O((max-min)/32);

void AndNums(int* a, int* b, int alen, int blen)
{
	int min = 0, max = 0;
	int *ps = NULL, *pl = NULL;
	int len = 0, longlen = 0;
	if (alen < blen)
	{
		ps = a;
		len = alen;
		longlen = blen;
		pl = b;
	}
	else
	{
		ps = b;
		len = blen;
		longlen = alen;
		pl = a;
	}
	min = max = ps[0];
	for (int i = 1; i < len; ++i)
	{
		if (ps[i] < min)
			min = ps[i];
		if (ps[i]>max)
			max = ps[i];
	}
	int gap = max - min;
	gap = gap / 32 + 1; //儲存差值要gap個int 型別的數
	int *extra = new int[gap];
	for (int i = 0; i < gap; ++i) extra[i] = 0;
	int outInd, inInd;
	for (int i = 0; i < len; ++i)
	{
		outInd = (ps[i] - min) / 32;
		inInd = (ps[i] - min) % 32;
		extra[outInd] |= 1 << inInd;
	}
	vector<int> res;
	for (int i = 0; i < longlen; ++i)
	{
		if ((pl[i] - min >= 0) && (pl[i] - min <= max - min))
		{
			outInd = (pl[i] - min) / 32;
			inInd = (pl[i] - min) % 32;
			if (0 != (extra[outInd] & (1 << inInd)))
			{
				res.push_back(pl[i]);
				cout << pl[i] << endl;
			}	
		}
	}
	cout << endl;
}
void main()
{
	int a[] = { 1, 5, 9, 8, 6, 4 };
	int b[] = { 9, 4, 2, 0, 5, 11, 12 };
	int alen = sizeof(a) / sizeof(int);
	int blen = sizeof(b) / sizeof(int);
	AndNums(a, b,alen,blen);
}

這種點陣圖法,其實在空間要求不高的情況下,還有一種解法;

開始時A[max]=B[max]={0};

A={ 1 5 9 8 6 4};則令 A[1]=1  A[5]=1  A[9]=1 A[8]=1 A[6]=1 A[4]=1

然後遍歷B i=1:lenth,判斷A[ B[i] ]是否為1,若是,則為交集,反之就不是;(但是,這種方法,當元素值為負數的時候就不好辦了)