查找2个排序列表的交集

时间:2016-09-30 01:09:56

标签: java linked-list set-intersection

我有一个任务 给出两个可比项目的排序列表, L1和L2。您可以假设在L1和 L2所有元素都不同(没有重复)但是t 他可能在L1和L2之间进行拦截 非空。

(b)中 实施有效的方法 用Java计算对称差(Δ) 在L1和L2之间,L1ΔL2。请记住 集合论,对称性 两组A和B的差异是A或B中的元素集,但两者都不是。 示例:假设A = {1,3,5,7,9}且B = {1,2,3,4,5},AΔB= {2,4,7,9}。

到目前为止我写了这个,但我不知道为什么它会在第一个列表的末尾停止搜索,并且不会继续检查第二个列表中的差异。有什么帮助吗?

    public static <AnyType extends Comparable<? super AnyType>>
        void symDifference(List<AnyType> L1, List<AnyType> L2,
                List<AnyType> Difference) 
{

    ListIterator<AnyType> iterL1 = L1.listIterator();
    ListIterator<AnyType> iterL2 = L2.listIterator();
    AnyType itemL1 = null;
    AnyType itemL2 = null;

    if (iterL1.hasNext() && iterL2.hasNext()) 
    {
        itemL1 = iterL1.next();
        itemL2 = iterL2.next();
    }

    while (itemL1 != null && itemL2 != null) 
    {
        int compareResult = itemL1.compareTo(itemL2);
        if (compareResult == 0) 
        {
            itemL1 = iterL1.hasNext() ? iterL1.next() : null;
            itemL2 = iterL2.hasNext() ? iterL2.next() : null;
        } 
        else if (compareResult < 0) 
        {
            Difference.add(itemL1);
            itemL1 = iterL1.hasNext() ? iterL1.next() : null;
        } 
        else
        {
            Difference.add(itemL2);
            itemL2 = iterL2.hasNext() ? iterL2.next() : null;
        }
    }
}

public static void main(String[] args)
{
    LinkedList<Integer> list1 = new LinkedList<>();
    LinkedList<Integer> list2 = new LinkedList<>();
    LinkedList<Integer> difList = new LinkedList<>();

    list1.add(1);
    list1.add(3);
    list1.add(5);
    list1.add(7);
    list1.add(9);

    list2.add(1);
    list2.add(2);
    list2.add(3);
    list2.add(4);
    list2.add(5);

    symDifference(list1,list2,difList);
    System.out.println(difList);

}
}

2 个答案:

答案 0 :(得分:0)

好吧,想一想。 list1 {1,2,3,5} list2 {1,5}。 正如shmosel所说,如果你的循环运行两次会发生什么?它退出循环和功能。 理想情况下,您希望浏览两个数组上的所有元素。

顺便说一句,我不认为你的解决方案也能正常工作(你可以这样做,但你的代码看起来会非常难看,可能需要O(list1.length * list2.length))。由于两个列表都已排序,因此您可以比较两个元素,并首先循环较小的元素列表。例如,使用list1和list2,比较1和1,两者相等,然后移动到2和5.然后比较2和5,将2加到列表中,然后移动2到3 ONLY 。需要O(list1.length + list2.length)。

答案 1 :(得分:0)

这是一个经典的陷阱。当一个列表运行干燥时,您的循环停止(应该如此)。此时你仍然想要耗尽其他列表。因此,在while循环之后插入逻辑以复制其他列表中的其余元素。既然你知道一个列表已经完成并且只剩下一个列表,但是你不知道哪个,那么简单的解决方案就是从两个列表中获取剩余的元素。由于两个列表都已排序,您知道列表中仍包含元素的其余部分不能包含run-dry列表中的任何元素,因此您只需将它们全部添加到结果中即可。总而言之,你可能会在循环之后添加两个while循环,一个用于iterL1,一个用于iterL2。由于每个都以线性时间运行,因此您的时间复杂度不会受到伤害。

相关问题