该题目来自58同城的二面,用最快速度求两个数组之交集算法。
比如A={6,2,4,1},B={2,9,4,3},那么A&B={2,4}。
算法一:在大多数情况,也就是一般的情况下,大家都能想出最暴力的解法,通常也就是采用遍历或者枚举的办法来解决问题。
该题需要找出两个数组的交集,最简单的一个办法就是用A数组里面的所有数去匹配B数组里面的数。假设两个数组的大小都是n,那么这种遍历的时间复杂度为O(n^2)。这个也是最复杂的情况了。
算法二:通常下,除了用暴力枚举的问题,还有另外一种外万金油的解法----预处理。其实思想和C语言中的预处理一样,对数据记性归一化处理。说白了,在这里就是对数组排序。我们知道数组排序的算法时间复杂度最低是O(nlogn),可以看到数量级已经低于算法一的时间复杂度。
那么在排好序好,怎么得到数组的交集呢?
假设我们已经有了两个排好序的数组:
A={1,2,4,6}
B={2,3,4,9}
那么我们只要分别对A和B设置两个指针i,j(或者直接说是下标),进行循环,伪代码如下:
int count()
{
total=i=j=0;while(i<n && j<n){if(a[i]<b[j]) i++;else if(a[i]>b[j])j++elsetotal++;}return total;
}
时间复杂度为O(n)
综合排序的时间复杂度则整体复杂度为:O(nlogn)
算法三:如果只是会了上面两种,还只能说是计算机的菜鸟,而且一般面试或者笔试题也不会这么简单。那么比O(nlogn)时间复杂度更低的是多少呢?一般就是O(n)。我们可以思考一下计数排序的算法。也就是把两个数组A和B都遍历到一个新的数组里,然后在统计重复的数字即可,这个时间复杂度就是O(n)。当然,计数排序是有条件的,也就是要求数组内数字的范围是已知并且不是很大。
算法四:上面的算法实现简单,也很容易达到题目的要求,但是还是有一些瑕疵,也就是非完美方案,同样根据算法三我们可以想出用哈希函数或者哈希表来解决问题。也就是将数组A哈希到哈希表中,然后继续将数组B哈希到哈希表中,如果发生哈希碰撞则统计加1,最后可以得出数组的交集。时间复杂度也就是哈希所有元素的复杂度O(n)。
文章来自IT部落格(www.itbuluoge.com)