每天学习一算法系列(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;
}
时间复杂度为O(n * logn)
思路二:
直接借用stl中的Map来求去交集,集体想法是:先把数组A中的元素插入到map中,把值当作Key, Value设置为1,然后用数组B中的元素作为Key去查询map,如果找到,并且值为1那就说明存在交集, 然后接着数组B的下个元素往下继续查找,如果没有找到,那么就记录下改交集的长度,然后依次往下查找,记录所有的交集,最后遍历完后,比较所有的交集找出最大的交集即可.
题目:已知两个数组,数组里的元素有正有负,但是都是按照从小到大已经排好序,要求用尽可能小的时间复杂度编写一算法求出两个数组的最大交集。如:
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的下个元素往下继续查找,如果没有找到,那么就记录下改交集的长度,然后依次往下查找,记录所有的交集,最后遍历完后,比较所有的交集找出最大的交集即可.
相关文章推荐
- Android中观察者模式的升入理解
- Linux内核里的DebugFS
- Linux的后台执行进程之nohup
- XZ_iOS中textField的键盘弹出和回收导致的界面上移和下移
- hihoCoder 1322:树结构判定
- 详解C语言 三大循环 四大跳转 和判断语句
- 【JLOI2015】战争调度(war)
- leetcode278.First Bad Version 关于有符号数加法溢出的错误
- 2851 菜菜买气球
- 使用缓存技术来提高性能之——OSCache缓存技术入门(二)
- Xcode 中的相对路径与绝对路径的相关设置
- spring的Scheduled(定时任务)和多线程
- 白话scala系列三 Scala编程难点解析
- 一个全屏PopupWindow的小问题
- IReport环境搭建
- 关于Unity中 截图跳转分享界面的问题
- 织梦dedecms栏目添加自定义字段,增加栏目上传缩略图功能
- iOS 图片不变形拉伸
- 创建session和session的赋值
- python之ansible 2.0 API