现在的位置: 首页 > 综合 > 正文

每天学习一算法系列(5)(已知两个数组,数组里的元素有正有负,但是都是按照从小到大已经排好序,要求用尽可能小的时间复杂度编写一算法求出两个数组的最大交集)

2013年02月18日 ⁄ 综合 ⁄ 共 1716字 ⁄ 字号 评论关闭

昨天刚刚去迅雷面试,总体感觉还不错,不过有的填空题目做错的太冤枉了,也都怪平时养成马虎的习惯,以后一定要改掉这样的毛病,总体来说题目质量还是不错的,有选择题,填空题,简答题,算法题,主要考C++对象模型的知识比较多,还零星的考一些COM相关题目,至于算法题还蛮简单的,有两道,第一道是反转链表,另外一道就是我这篇文章所要讲的题目。

 

题目:已知两个数组,数组里的元素有正有负,但是都是按照从小到大已经排好序,要求用尽可能小的时间复杂度编写一算法求出两个数组的最大交集。如:

A[] = {-10,5, 6},

B[] = {2, 4, 5, 6, 12};

那么交集为: {5, 6}

 

 

思路一:

顺序取出数组A中的每个元素,然后对取出的每个元素在数组B中进行二分查找,如果没有找到,一直到结束,如果找到,假如找到的元素在B中的Index为J,在A中的Index为I,那么从I+1,J+1开始对两个数组进行取元素并进行比较,如果相等则一直继续,如果不相等,那么从Index I到当前Index-1就是两个数组的最大交集.

 

代码如下:

/*---------------------------------
Copyright by yuucyf. 2011.04.26
求两数组的最大交集
----------------------------------*/

#include "stdafx.h"
#include <assert.h>


int FindValue(const int *pB, int i32FirIdx, int i32EndIdx, int nValue)
{
	assert(NULL != pB);

	if (i32FirIdx > i32EndIdx)	return -1;

	int i32MidIdx = (i32FirIdx + i32EndIdx) / 2;
	if (pB[i32MidIdx] > nValue)
	{
		return FindValue(pB, i32FirIdx, i32MidIdx - 1, nValue);
	}
	else if (pB[i32MidIdx] < nValue)
	{
		return FindValue(pB, i32MidIdx + 1, i32EndIdx, nValue);
	}

	return i32MidIdx;
}


bool GetMaxSubArray(const int *pA, int nASize, const int *pB, int nBSize)
{
	assert(NULL != pA || NULL != pB);
	assert(0 <= nASize || 0 <= nBSize);

	int i32Idx = -1;
	int i32I = 0, i32J = 0;

	for (i32I = 0; i32I < nASize; i32I++)
	{
		if ((i32Idx = FindValue(pB, 0, nBSize - 1, pA[i32I])) != -1)
		{
			printf("Max sub array is : %d ", pA[i32I]);
			for (i32I++, i32J = i32Idx + 1; i32I < nASize && i32J < nBSize; i32I++, i32J++)
			{
				if (pA[i32I] == pB[i32J])
				{
					printf("%d ", pA[i32I]);
				}
			}

			return true;
		}
	}

	return false;
}


int _tmain(int argc, _TCHAR* argv[])
{
	int aryA[] = {-10, 5, 6};
	int aryB[] = {2, 4, 5, 6, 12};
	if (!GetMaxSubArray(aryA, sizeof(aryA)/sizeof(int), aryB, sizeof(aryB)/sizeof(int)))
	{
		printf("Not sub array!\n");
	}

	return 0;
}

 

 

时间复杂度为O(n * logn)

 

思路二:
    直接借用stl中的Map来求去交集,集体想法是:先把数组A中的元素插入到map中,把值当作Key, Value设置为1,然后用数组B中的元素作为Key去查询map,如果找到,并且值为1那就说明存在交集, 然后接着数组B的下个元素往下继续查找,如果没有找到,那么就记录下改交集的长度,然后依次往下查找,记录所有的交集,最后遍历完后,比较所有的交集找出最大的交集即可.

 

抱歉!评论已关闭.