如果你有N个排序数组,其中可能的元素是从0到N-1的整数,并且单个数组中的元素是不同的,你如何检查是否至少有两个数组,至少有两个元素是常见的?
例如,如果我有以下数组,其中N = 5:
A[0] = {0},
A[1] = {1, 3},
A[2] = {2},
A[3] = {1, 4},
A[4] = {1, 3}
然后A [1]和A [4]共有1和3,因此答案是正确的。
在N再次为5的其他例子中:
A[0] = {0, 4},
A[1] = {1, 3},
A[2] = {1, 2, 4},
A[3] = {0, 3},
A[4] = {1}
没有两个数组A [i],A [j]至少有两个共同的元素,因此答案是错误的。
这是一个采访问题的一部分,我只能在O(n ^ 3)时间内通过遍历每个数组组合(A [i],A [j])来解决,并且在每次迭代中我从0扫描到N-1以检查有两个共同的元素。
采访者表示有一个更快的解决方案,有点暗示利用阵列的排序,但即使我在过去24小时内考虑到这个问题,我也无法提出更好的解决方案
什么是比O(N ^ 3)更快的算法来解决这个问题? 谢谢。
答案 0 :(得分:6)
使用数组顶点和数字顶点(最多2N个顶点)创建图形 将每个数组顶点与其数字连接起来 如果两个数组有一对公共数字,则存在长度= 4的周期(图中的B-1-C-2)
查找if such cycle exists
创建图形和搜索周期都需要O(N ^ 2)
答案 1 :(得分:1)
在n = number of elements
和m = number of arrays
pointers[m] // one pointer for every array starting at begin();
commons[m][m] = 0 // count commons for every array combination
while(any pointer != end() )
{
find pointer with lowest value;
if any other pointer has this value;
common[x][y] ++; // increment the commons counter for the corresponding arrays
increment chosen pointer;
}
where common[x][y] >= 2 -> arrays contain 2 or more common elements
算法“一次”遍历所有数组,始终继续使用最小的元素。
将此元素与其他数组中最小的未访问元素进行比较。
如果元素相等,则在commons
数组中不采用not来跟踪公共元素的数量。
在访问每个元素之后,您只需要查看common
矩阵以查看哪些数组具有两个以上的公共元素。