在java中查找arraylists中常见元素的索引

时间:2015-01-08 20:55:58

标签: java arraylist

我有几个没有重复元素的ArrayLists。我想在每个arraylist中找到它们的交集并返回共同元素的索引 例如,如果我输入为{0,1,2},{3,0,4},{5,6,0},那么我想在这里返回{0},{1},{2},即公共元素0的索引。
我能想到的一种方法是在所有ArrayLists上使用连续retainAll()来获取交集,然后使用indexOf()为每个输入ArrayList查找交集元素的索引。
有没有更好的方法呢?

2 个答案:

答案 0 :(得分:1)

首先对列表进行排序至少需要O(nlogn)次。如果您正在寻找更高效的算法,可以使用哈希映射获得O(n)

例如

A=[0,1,2],B=[3,0,4],C=[5,6,0]

您可以循环遍历每个列表,并在元素上附加带有哈希的元素。最终的哈希看起来像

H = {0:[0,1,2], 1:[1], 2:[2], 3:[0], 4:[2], 5:[0], 6:[1]}

这里,键是元素,值是它对应列表中的索引。现在,只需循环遍历hashmap,找到大小为3的任何列表,在这种情况下,获取索引。


代码看起来像这样(未经测试):

int[][] lists = {{0,1,2}, {3,0,4}, {5,6,0}};

// Create the hashmap
Map<Integer, List<Integer>> H = new HashMap<Integer, List<Integer>>();
for(int i = 0; i < lists.length; i++){
    for(int j = 0; j < lists[0].length; j++){
        // create the list if this is the first occurance
        if(!H.containsKey(lists[i][j]))
            H.put(lists[i][j], new ArrayList<Integer>());

        // add the index to the list
        H.get(lists[i][j]).add(j);
    }
}

// Print out indexes for elements that are shared between all lists
for(Map.Entry<Integer, List<Integer>> e : H.entrySet()){
    // check that the list of indexes matches the # of lists
    if(e.getValue().size() == lists.length){
        System.out.println(e.getKey() + ":" + e.getValue());
    }
}

编辑:刚刚注意到你建议在你的问题中使用retainAll()。那也是O(n)。

答案 1 :(得分:0)

这是一个非常低效但相当可读的解决方案,使用流返回列表列表。

int source[][];

Arrays.stream(source)
    .map(list -> IntMap.range(0, list.length)
        .filter(i -> Arrays.stream(source)
            .allMatch(l -> Arrays.binarySearch(l, list[i]) >= 0))
        .collect(Collectors.toList()))
    .collect(Collectors.toList());

如果需要,您可以添加toArray调用以转换为数组。