我有以下问题:我需要在两个列表中找到相同元素的对,这些列表是无序的.关于这两个列表的事情是它们“大致相等” – 只有某些元素被一些索引移动,例如(注意,这些对象不是整数,我只是在这个例子中使用整数):
[1,2,3,5,4,8,6,7,10,9]
[1,2,3,4,5,6,7,8,9,10]
我的第一次尝试是迭代两个列表,并根据每个对象的一些唯一键生成两个HashMaps.然后,在第二遍时,我只需从两个地图中拉出元素.这在空间和时间上产生O(2N).
我正在考虑一种不同的方法:我们将保留指向两个列表中当前元素的指针,以及每个列表的当前未匹配集.伪代码将是以下类型:
while(elements to process)
elem1 = list1.get(index1)
elem2 = list2.get(index2)
if(elem1 == elem2){ //do work
... index1++;
index2++;
}
else{
//Move index of the list that has no unamtched elems
if(firstListUnmatched.size() ==0){
//Didn't find it also in the other list so we save for later
if(secondListUnamtched.remove(elem1) != true)
firstListUnmatched.insert(elem1)
index1++
}
else { // same but with other index}
}
以上可能不起作用……我只是想大致了解你对这种方法的看法.基本上,这在每个列表的一侧维护一个散列集,其大小<
最佳答案
I cannot simply return a set intersection of two object lists, as I need to perform operations (multiple operations even) on the objects I find as matching/non-matching
您可以维护一组不匹配的对象.这将是空间中的O(M),其中M是任何点处交换元素的最大数量.对于N是元素数的时间,它将是O(N).
interface Listener {
void matched(T t1);
void onlyIn1(T t1);
void onlyIn2(T t2);
}
public static void compare(List list1, List list2, Listener tListener) {
Set onlyIn1 = new HashSet();
Set onlyIn2 = new HashSet();
for (int i = 0; i < list1.size(); i++) {
T t1 = list1.get(i);
T t2 = list2.get(i);
if (t1.equals(t2)) {
tListener.matched(t1);
continue;
}
if (onlyIn2.remove(t1))
tListener.matched(t1);
else
onlyIn1.add(t1);
if (!onlyIn1.remove(t2))
onlyIn2.add(t2);
}
for (T t1 : onlyIn1)
tListener.onlyIn1(t1);
for (T t2 : onlyIn2)
tListener.onlyIn2(t2);
}