Java:两个有序整数序列的交集

Java:两个有序整数序列的交集,java,arrays,integer,Java,Arrays,Integer,可能重复: 如果我有两个有序的数字序列,我在这里有很大的灵活性,可以将我的数据放在列表、集合、数组等中,那么提取匹配项的最有效方法是什么?例如,如果我有: [1,2,4,6,9]和[2,3,4],我想返回[2,4] 显然有很多方法可以做到这一点;我很好奇什么是最有效的方法。那么你想要to集的交集? 您可以从apache commons使用。或者更好,是番石榴属的。这是两个系列的交叉点,我想这是最好的选择 请看 仅保留此集合中包含在指定集合可选操作中的元素。换句话说,从该集合中删除指定集合中不包

可能重复:

如果我有两个有序的数字序列,我在这里有很大的灵活性,可以将我的数据放在列表、集合、数组等中,那么提取匹配项的最有效方法是什么?例如,如果我有:

[1,2,4,6,9]和[2,3,4],我想返回[2,4]


显然有很多方法可以做到这一点;我很好奇什么是最有效的方法。

那么你想要to集的交集? 您可以从apache commons使用。或者更好,是番石榴属的。这是两个系列的交叉点,我想这是最好的选择

请看

仅保留此集合中包含在指定集合可选操作中的元素。换句话说,从该集合中删除指定集合中不包含的所有元素

更有效的方法是

public static void main(String[] args) {
    int[] firstArray = { 1, 3, 5, 8, 10 };
    int[] secondArary = { 3, 8 };
    //Arrays.sort(firstArray); If arrays needs to be sorted
    //Arrays.sort(secondArary);
    System.out.println(Arrays
            .toString(intersection(firstArray, secondArary)));

}

private static Integer[] intersection(int firstArray[], int secondArary[]) {
    int i = 0;
    int j = 0;
    ArrayList<Integer> list = new ArrayList<Integer>();
    while (i < firstArray.length && j < secondArary.length) {
        if (firstArray[i] < secondArary[j])
            i++;// Increase I move to next element
        else if (secondArary[j] < firstArray[i])
            j++;// Increase J move to next element
        else {
            list.add(secondArary[j++]);
            i++;// If same increase I & J both
        }
    }
    return list.toArray(new Integer[0]);
}

如果将两个序列存储到集合中,则可以使用Set.retainal,它:

仅保留此集合中包含在指定集合可选操作中的元素。换句话说,从该集合中删除指定集合中不包含的所有元素。如果指定的集合也是一个集合,则此操作会有效地修改该集合,使其值为两个集合的交点

例如:

Set<Integer> s1 = new TreeSet<Integer>();
s1.add(1);
s1.add(2);
s1.add(6);

Set<Integer> s2 = new TreeSet<Integer>();
s2.add(2);
s2.add(6);

s2.retainAll(s1);

for (Integer i: s2)
{
    System.out.println(i);
}
输出:

2 6
我将创建两个列表作为java.util.Set,将一个集合复制到一个临时变量,并在这个临时集合上调用retainAll。然后,临时集合将保留在两个集合的交点处。

两个指针索引,每个列表一个指针索引。从每个列表的开头开始

无论何时找到匹配项,都要存储它

如果没有匹配项,请检查当前索引中哪个列表的值最低,并增加该列表的索引。检查是否匹配。这样做直到你到达其中一个列表的末尾

在最坏的情况下,与列表和的大小成线性关系。没有办法做得更好。

我会使用并执行以下操作:

TreeList<Integer> list1 = ...
TreeList<Integer> list2 = ...

Iterable<Integer> result = Iterables.filter(list1, Predicates.in(list2));

这使用了番石榴的可数名词和谓词。

以下是相同的问题序列是否包含重复的数字?请检查这个不会在线性时间内运行的问题。它将迭代目标集,通过hashcode在原始集中搜索一个HashSet,然后逐个删除。这不会在线性时间内运行。它将在目标集上迭代,在原始集合顺序logn中搜索树集,然后逐个删除。@灰色假设第一个集合不需要是树集,它可以是一个哈希集,这将为您提供一个O1 on contains。@assylias但我的观察是,如果是短数组集,则需要更多的时间来构造哈希集本身。