题目就是假设有三个有序数组对其求交集,要求算法空间复杂度必须小,有序数组量会比较大。
解法:
第一种就是用二分法查找,二分法查找的效率是log(n),两个数组求交集就是n1log(n2),当n1远小于n2的时候,这个算法效果可以
第二种就是遍历,用两个游标来实现,具体可以见代码,算法效率o(n1+n2)线性,当n1和n2比较接近时效果可以

#include<iostream>
#include<cstdlib>
#include<vector>
#include<list>
#include<algorithm>
#include<ctime>using std::vector;
using std::list;//获取一个大小为num,有序的数组vecInt,数组中最大的数值为 max*num
void getRandOrderIntVec(vector<int>& vecInt, int num,int max)
{vecInt.clear();vecInt.reserve(num);while (vecInt.size() < num){if (vecInt.empty()){int value = (std::rand() % (max));vecInt.push_back(value);}else {int value = (std::rand() % max ) + vecInt.back() + 1;vecInt.push_back(value);}}}//********************遍历法查找相同的数据**********************************
//找出三个数组中相同的数值,并且保存在vecSame的vector中
void getSameValue(vector<int>& vec1, vector<int>& vec2, vector<int>& vec3, vector<int>& vecSame)
{vecSame.clear();//先确定一个保存交集的空间大小int minNumInThreeVec = vec1.size();if (vec2.size() < minNumInThreeVec){minNumInThreeVec = vec2.size();}if (vec3.size() < minNumInThreeVec){minNumInThreeVec = vec3.size();}minNumInThreeVec /= 2; vecSame.reserve(minNumInThreeVec);//***********************查找交集**************************vector<int>::iterator vecIter1 = vec1.begin();vector<int>::iterator vecIter2 = vec2.begin();vector<int>::iterator vecIter3 = vec3.begin();while ((vecIter1 != vec1.end())& (vecIter2 != vec2.end())& (vecIter3 != vec3.end())){//如果相等的话if (((*vecIter1) == (*vecIter2))& ((*vecIter2) == (*vecIter3))){vecSame.push_back(*vecIter1);//记录这个数值//将三个迭代器都后移if ((vecIter1 != vec1.end())& (vecIter2 != vec2.end())& (vecIter3 != vec3.end())){vecIter1++;vecIter2++;vecIter3++;}else{return; //有迭代器到最后了}}//如果不相等的话,将最小数值的迭代器后移else{int caseValue = 0;int minValue = (*vecIter1);if (minValue > (*vecIter2)){minValue = (*vecIter2);caseValue = 1;}if (minValue > (*vecIter3)){caseValue = 2;}//后移指向数据最小的迭代器switch (caseValue){case 0:{if (vecIter1 != vec1.end()){vecIter1++;break;}else{return;}}case 1:{if (vecIter2 != vec2.end()){vecIter2++;break;}else{return;}}case 2:{if (vecIter3 != vec3.end()){vecIter3++;break;}else{return;}}default:break;}}}
}//***********************二分法查找相同的数据*************************void getSameValueByBinarySeach3(vector<int>& vec1, vector<int>& vec2, vector<int>& vec3, vector<int>& vecSame)
{vecSame.clear();//先确定一个保存交集的空间大小int minNumInThreeVec = vec1.size();if (vec2.size() < minNumInThreeVec){minNumInThreeVec = vec2.size();}if (vec3.size() < minNumInThreeVec){minNumInThreeVec = vec3.size();}minNumInThreeVec /= 2;vecSame.reserve(minNumInThreeVec);//这里直接假设vec1是最小的集合,vec2第二小,vec3最大vector<int>::iterator pos2Iter =  vec2.end(); vector<int>::iterator pos3Iter =  vec3.end();for (int i = (vec1.size()-1); i >= 0; i--){pos2Iter = std::lower_bound(vec2.begin(), pos2Iter, vec1[i]); //缩小二分查找的范围if ((*pos2Iter) == vec1[i]){pos3Iter = std::lower_bound(vec3.begin(), pos3Iter, vec1[i]);//缩小二分查找的范围if ((*pos3Iter) == vec1[i]){vecSame.push_back(vec1[i]);}}}
}void getSameValueByBinarySeach2(vector<int>& vec1, vector<int>& vec2, vector<int>& vec3, vector<int>& vecSame)
{vecSame.clear();//先确定一个保存交集的空间大小int minNumInThreeVec = vec1.size();if (vec2.size() < minNumInThreeVec){minNumInThreeVec = vec2.size();}if (vec3.size() < minNumInThreeVec){minNumInThreeVec = vec3.size();}minNumInThreeVec /= 2;vecSame.reserve(minNumInThreeVec);//这里直接假设vec1是最小的集合,vec2第二小,vec3最大vector<int>::iterator pos2Iter= std::lower_bound(vec2.begin(), vec2.end(), vec1.back()); //缩小二分查找的范围vector<int>::iterator pos3Iter = std::lower_bound(vec3.begin(), vec3.end(), vec1.back());for (int i = 0; i < vec1.size(); i++){if (std::binary_search(vec2.begin(), pos2Iter, vec1[i])){if (std::binary_search(vec3.begin(), pos3Iter, vec1[i])){vecSame.push_back(vec1[i]);}}}
}void getSameValueByBinarySeach(vector<int>& vec1, vector<int>& vec2, vector<int>& vec3, vector<int>& vecSame)
{vecSame.clear();//先确定一个保存交集的空间大小int minNumInThreeVec = vec1.size();if (vec2.size() < minNumInThreeVec){minNumInThreeVec = vec2.size();}if (vec3.size() < minNumInThreeVec){minNumInThreeVec = vec3.size();}minNumInThreeVec /= 2;vecSame.reserve(minNumInThreeVec);//这里直接假设vec1是最小的集合,vec2第二小,vec3最大for (int i = 0; i < vec1.size(); i++){if (std::binary_search(vec2.begin(), vec2.end(), vec1[i])){if (std::binary_search(vec3.begin(), vec3.end(), vec1[i])){vecSame.push_back(vec1[i]);}}}
}void printVec(vector<int>& vec)
{for (int i = 0; i < vec.size(); i++){std::cout << vec[i] << "  ";}std::cout << std::endl;
}bool ifTwoVecSame(vector<int>& vec1, vector<int>& vec2)
{if (vec1.size() != vec2.size()){return false;}for (int i = 0; i < vec1.size(); i++){if (vec1[i] != vec2[i]){return false;}}return true;
}
int main()
{vector<int> vec1;vector<int> vec2;vector<int> vec3;getRandOrderIntVec(vec1, 300000,100);getRandOrderIntVec(vec2, 50000000,60);getRandOrderIntVec(vec3, 100000000,60);//printVec(vec1);//printVec(vec2);//printVec(vec3);//****遍历法求交*************std::cout <<  "遍历法求交集"  <<std::endl;vector<int> sameVec;clock_t startTime, endTime;startTime = clock();getSameValue(vec1, vec2, vec3,sameVec);endTime = clock();std::cout << "遍历法运行时间 " << (endTime - startTime)  <<std::endl;//printVec(sameVec);std::cout << "交集数目 :" << sameVec.size() << std::endl;//***********二分法求交***************std::cout << "二分法求交集" << std::endl;vector<int> sameVec2;clock_t startTime2, endTime2;startTime2 = clock();getSameValueByBinarySeach(vec1, vec2, vec3, sameVec2);endTime2 = clock();std::cout << "二分法运行时间 " << (endTime2 - startTime2) << std::endl;//printVec(sameVec2);std::cout << "交集数目 :" << sameVec2.size() << std::endl;//****遍历法和二分法结果比较*****************std::cout << "两种方法结果相同1,不同 0: " << ifTwoVecSame(sameVec, sameVec2) << std::endl;//***********二分法求交3***************std::cout << "二分法求交集3" << std::endl;vector<int> sameVec3;clock_t startTime3, endTime3;startTime3 = clock();getSameValueByBinarySeach3(vec1, vec2, vec3, sameVec3);endTime3 = clock();std::cout << "二分法运行时间3 " << (endTime3 - startTime3)  << std::endl;//printVec(sameVec2);std::cout << "交集数目3 :" << sameVec3.size() << std::endl;//****遍历法和二分法结果比较*****************std::cout << "两种方法结果相同1,不同 0: " << ifTwoVecSame(sameVec, sameVec3) << std::endl;
}

腾讯实习笔试:关于几个有序数组求交集的问题相关推荐

  1. 面试题之2个有序数组求合并后的中位数

    问题出处: http://fayaa.com/tiku/view/114/ 2个有序数组求合并后的中位数   第一步:假设两个有序数组(已经各自排序完成了)长度相等,试写函数找出两个数组合并后的中位数 ...

  2. 【两个有序数组求中位数】

    /* 两个有序数组求中位数问题; 这个题有很多方法: 方法一:排序,找到中位数: 方法二:归并排序的思想 方法三:转换成求第k小值   */ /* 思路:使用二分查找,时间复杂度为log(m+n). ...

  3. Leetcode算法题:两个有序数组求中位数

    Leetcode算法题:两个有序数组求中位数 要求时间复杂度为O(log(m+n)) 思路: 暴力解决:合并数组并排序,简单且一定能实现,时间复杂度O(m+n) 由于两个数组已经排好序,可一边排序一边 ...

  4. 两个有序数组求中位数的三种解法

    寻找两个有序数组的中位数(附上三种解法)_BoCong-Deng的博客-CSDN博客_两个有序数组求中位数

  5. 菜鸡的2020年腾讯实习笔试

    2020年4月26日的腾讯实习生笔试,一共有五道题,给了两个小时.感觉都比较简单,甚至没有粤澳CPC的网络赛难,但是我太菜了,只做出了三道题. 第一道题是签到题:(每一道题我都wa了一遍,可能是紧张导 ...

  6. 如歌将两个数组合并_腾讯50题---合并两个有序数组

    题目描述: 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 ...

  7. 有序数组求中位数问题

    1.有两个已排好序的数组A和B,长度均为n,找出这两个数组合并后的中间元素,要求时间代价为O(logn). 2.假设两个有序数组长度不等,同样的求出中位数. 一:解析: 这个题目看起来非常简单.第一题 ...

  8. LeetCode 1213. 三个有序数组的交集(哈希set)

    文章目录 1. 题目 2. 解题 1. 题目 给出三个均为 严格递增排列 的整数数组 arr1,arr2 和 arr3. 返回一个由 仅 在这三个数组中 同时出现 的整数所构成的有序数组. 示例: 输 ...

  9. 两个有序数组求中位数log(m+n)复杂度

    leetcode 第4题 中位数技巧: 对于长度为L的有序数组,它的中位数是(a[ceil((L+1)/2)]+a[floor((L+1)/2)])/2 算法原理: 类似三分法求极值 两个人都前进,谁 ...

最新文章

  1. 分布式架构知识体系必读
  2. MySQL时间格式TIMESTAMP和DATETIME的区别
  3. sql事务、视图和索引
  4. Spring框架–应用程序上下文–到达应用程序上下文的三种方法
  5. 【dll 返回字符串 】2
  6. php csrf攻击 xss区别,XSS与CSRF攻击及防御方法
  7. java final class 性能_java中final修饰基本变量后的效率问题
  8. js 高级 原型对象
  9. Java关闭窗口和刷新
  10. 编程时遇到问题的解决方向
  11. CentOS或Linux中,查看Tomcat版本的三种方式
  12. 结构体习题:有5个职工,每个职工的数据包括:职工号、姓名、工资,编写程序要求从键盘上输入职工们的数据,输出高于平均工资的职工信息及高于平均工资的职工人数。——[C语言]入门基础编程 1092
  13. java excel 数组公式_Apache poi中的数组公式
  14. android坐标计算器,函数科学计算器算坐标
  15. Android推送技术总结
  16. 鸿蒙时期人物排行榜,《永生》之战力排行榜,那些经典角色你还记得吗
  17. 一次linux oops分析
  18. 加油,打工人~杨斯维特珍视您的每一滴汗水!
  19. 温湿度控制系统c语言,基于单片机的温湿度控制系统设计
  20. 美化win10 PowerShell

热门文章

  1. Object-c学习之路三(@class与#import的区别)
  2. VC中海量文件读写类设计与应用(转)
  3. return true Java方法_java - 如何检查方法是否返回true或false?_java_酷徒编程知识库...
  4. jade模板引擎修改为ejs模板引擎
  5. 使用localStorage解决浏览器刷新后无法再从vuex中获取数据的问题
  6. centos7输入systemctl status network.service出现Unit network.service could not be found的解决办法
  7. c语言模板程序,模板模式 (C语言实现)
  8. 深入理解Java虚拟机(类文件结构)
  9. webpack - 收藏集 - 掘金
  10. MySQL实现差集(Minus)和交集(Intersect)