我有两个数组array1 = Array<List<Integer>>
和array2 = Array<Integer>
,我遍历array2
。然后,我尝试找到array1
中array2
中当前项目的列表。我从array1
检索相应的列表并遍历它以查看我是否可以在array1
中找到相似的数字。我将相似性定义为某个错误epsilon中的相等数字(即6
将7
与epsilon=1
7-6=1
相等。如果数字相等,我将它们添加到名为matchList
的列表中。最后,我有一个名为matchList
的{{1}}列表。
这是一些伪代码:
resultList
我的问题是,我是否可以提高List<List<Integer>> resultList = new ArrayList<List<Integer>>();
for (i = 0; i < array2.length; i++) {
int index = array2[i] % n;
List<Integer> currentList = array1[index];
List<Integer> matchList = new LinkedList<Integer>();
while(int currentItem : currentList) {
if (currentItem - array2[i] < epsilon){
matchList.add(currentItem);
}
}
if (!matchList.isEmpty()){
resultList.add(matchList);
}
}
算法的复杂性。通过预先分配数组,使用迭代器遍历链表并使用原始类型集合(Trove而不是Java的内置函数)和其他一些措施,我已经大大提高了算法的速度。
编辑:我只对改进big-O运行时的建议感兴趣。
答案 0 :(得分:1)
为了在算法上解决这个问题(简单地按照评论中的建议并行运行算法不会降低算法的复杂性),您需要引入更高效的数据结构,以便您更快地查找。
您首先要创建存储桶,其中每个存储桶包含给定范围内的值(value
加/减epsilon
)。因此列表值可以在几个桶中。您可以至少O(n * #buckets)
创建此存储桶列表,可能更少,具体取决于您是否对值的分布有假设。
接下来,您可以针对这些存储分区检查其他列表。根据您的范围与这些存储桶的值的比率,可能有效地懒惰地创建存储桶并在某种哈希表中组织存储桶本身。然后,您将遍历另一个列表并检查存储桶的包含值,这可以在O(m)
时间内完成。
总共会留下O(n * #buckets + m)
。