您的位置:首页 > 其它

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

2016-07-04 10:03 841 查看
昨天刚刚去迅雷面试,总体感觉还不错,不过有的填空题目做错的太冤枉了,也都怪平时养成马虎的习惯,以后一定要改掉这样的毛病,总体来说题目质量还是不错的,有选择题,填空题,简答题,算法题,主要考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就是两个数组的最大交集.

代码如下:

[cpp]
view plain
copy

print?

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



/*---------------------------------
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的下个元素往下继续查找,如果没有找到,那么就记录下改交集的长度,然后依次往下查找,记录所有的交集,最后遍历完后,比较所有的交集找出最大的交集即可.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: