【发布时间】:2011-12-14 11:30:01
【问题描述】:
我有两个ArrayList<Long>,每个都有大约 5,00,000 个大小。我曾尝试使用 for 循环,其用法为 list.contains(object),但它需要太多时间。我尝试拆分一个列表并在多个线程中进行比较,但没有找到有效的结果。
我需要号码。两个列表中相同的元素。
有什么优化的方法吗?
【问题讨论】:
我有两个ArrayList<Long>,每个都有大约 5,00,000 个大小。我曾尝试使用 for 循环,其用法为 list.contains(object),但它需要太多时间。我尝试拆分一个列表并在多个线程中进行比较,但没有找到有效的结果。
我需要号码。两个列表中相同的元素。
有什么优化的方法吗?
【问题讨论】:
让l1 成为第一个列表,l2 成为第二个列表。在大 O 表示法中,它运行在 O(l1*l2)
另一种方法是将一个列表插入HashSet,然后测试另一个列表中的所有其他元素是否存在于HashSet中。这将大致给出2*l1+l2 -> O(l1+l2)
【讨论】:
HashSet 仅包含 一个 值,在您的情况下是您正在存储的 Long。
HashSet 并阅读HashMap。而且由于他正在寻找副本,因此在单个列表中删除副本不是问题。
l1 + (l2 * log (l1)),因为在l1 中查找l2 的每个元素需要O(log(l1))
O(1)
一般机制是对两个列表进行排序,然后迭代排序的列表以查找匹配项。
【讨论】:
当你有很多元素时,列表不是一种有效的数据结构,当你搜索一个元素时你必须使用更有效的数据结构。 例如树或哈希图!
【讨论】:
假设列表一有 m 个元素,列表二有 n 个元素,m>n。如果元素不是按数字排序的,那么它们似乎不是,比较步骤的总数 - 这是方法的成本 - 因子 mxn - n^2/2。在这种情况下,成本因子约为 50000x49999。
保持两个列表有序将是最佳解决方案。如果列表是有序的,这些比较的成本将是因子 m。在这种情况下,大约是 50000。当两个列表都通过两个游标进行迭代时,将达到最佳结果。该方法可以用如下代码表示:
int i=0,j=0;
int count=0;
while(i<List1.size() && j<List2.size())
{
if(List1[i]==List2[j])
{
count++;
i++;
}
else if(List1[i]<List2[j])
i++;
else
j++;
}
如果您可以始终保持列表有序,则此方法将有所不同。另外我认为除非对列表进行排序,否则不可能进行拆分和比较。
【讨论】: