1. 题目:找出两个有序数组的交集。
2. 解析:给定数组a和b,a的长度为m,b的长度为n
(1)最原始的方法,依次遍历a中每一个元素,并通过遍历b来判断a中元素是否在b中。时间复杂度O(m×n)
(2)改进的算法,在b中查找a的元素改为二分查找,时间复杂度为O(mlgn)
(3)因为a和b都是有序的,遍历a和b,并对a和b中的元素进行判断,如果a[i]<b[j] i++, 如果a[i]>b[j] j++, 如果a[i]==b[j] i++, j++。时间复杂度为O(m+n)
3. 分析:
(1)当m很小,n很大时,O(mlgn)二分法查找的效率高于线性查找的O(m+n),剩下的情况,线性查找效率比较高。
(2)当a和b中存在重复元素时,比如a={1,1,2,2,3},b={1,2,3}这时候使用(1)和(2)方法得到结果为:{1,1,2,2,3},使用(3)方法得到结果为:{1,2,3}。结果2更符合题目的要求。所以在有重复元素时,解法(3)更符合题目要求。
4. 代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cassert> 3 4 using namespace std; 5 6 void arrayIntersection(int* a, int aLength, int* b, int bLength) 7 { 8 if (!a || !b) 9 { 10 return ; 11 } 12 int i=0; 13 int j=0; 14 while ((i<aLength) && (j<bLength)) 15 { 16 if (a[i]<b[j]) 17 { 18 i++; 19 } 20 else if (a[i]>b[j]) 21 { 22 j++; 23 } 24 else 25 { 26 cout<<a[i]<<" "; 27 i++; 28 j++; 29 } 30 } 31 cout<<endl; 32 } 33 34 int main() 35 { 36 enum {aLength=5,bLength=7}; 37 int a[aLength]={1,4,4,5,6}; 38 int b[bLength]={4,5,6,7,9,10,11}; 39 arrayIntersection(a,aLength,b,bLength); 40 return 0; 41 }
5. 参考文章:
http://www.leetcode.com/2010/03/here-is-phone-screening-question-from.html
http://www.cnblogs.com/ZJUKasuosuo/archive/2012/06/12/BinarySearch.html