【发布时间】:2013-02-23 03:44:14
【问题描述】:
给定 N 个大小为 N 的数组,并且它们都是已排序的,如果它不允许您使用额外的空间,如何有效地或以更少的时间复杂度找到它们的共同数据?
例如:
1. 10 160 200 500 500
2. 4 150 160 170 500
3. 2 160 200 202 203
4. 3 150 155 160 300
5. 3 150 155 160 301
这是一个面试问题,我发现了一些类似的问题,但它们不包括输入被排序或无法使用额外内存的额外条件。
我想不出任何低于 O(n^2 lg n) 复杂度的解决方案。在这种情况下,我宁愿选择最简单的解决方案,它会给我带来这种复杂性,即:
not_found_flag = false
for each element 'v' in row-1
for each row 'i' in the remaining set
perform binary search for 'v' in 'i'
if 'v' not found in row 'i'
not_found_flag = true
break
if not not_found_flag
print element 'v' as it is one of the common element
我们可以通过比较每行的最小值和最大值来改进这一点,并据此决定数字“num”是否可能介于该行的“min_num”和“max_num”之间。
二分查找 -> O(log n) 在 n-1 行中搜索 1 num:O(nlogn) 对第一行中的每个数字进行二进制搜索:O(n2logn)
我选择了第一行,我们可以选择任何行,如果在任何 (N-1) 行中找到所选行的任何元素,那么我们实际上没有公共数据。
【问题讨论】:
-
您需要“一些”额外空间来存储(可能的)常见元素...
-
@MitchWheat。请看上面的伪代码。如果我们只打印常见元素就可以了,我们真的需要额外的存储空间吗?
-
你真的是通过二分搜索来保存任何东西吗?既然你需要找到所有常见的元素,为什么不直接扫描排序后的数组并在 O(n) 中完成
-
@smk。有“N”个不同的数组,每个数组都是独立排序的。我已经用示例编辑了这个问题。通过扫描“N”个数组,我们无法在 O(n) 中找到公共元素。它更像是一个 NXN 方阵,其中每一行都是单独排序的。