[英]Find indices of common elements in arraylists in java
I have several ArrayLists with no repeated elements. 我有几个没有重复元素的ArrayLists。 I want to find their intersection and return indices of common elements in each arraylist.
我想在每个arraylist中找到它们的交集并返回常用元素的索引。
For example, if I have input as {0,1,2},{3,0,4},{5,6,0}
, then I want to return {0},{1},{2}
ie indices of common element 0 here. 例如,如果我输入为
{0,1,2},{3,0,4},{5,6,0}
,那么我想返回{0},{1},{2}
即索引这里的共同元素0。
One way I can think of is to use succesive retainAll()
on all ArrayLists to get intersection, and then finding indices of elements of intersection using indexOf()
for each input ArrayList. 我能想到的一种方法是在所有ArrayLists上使用连续的
retainAll()
来获取交集,然后使用indexOf()
为每个输入ArrayList查找交集元素的索引。
Is there a better way to do that ? 有没有更好的方法呢?
Sorting the list first would require at least O(nlogn)
time. 首先对列表进行排序至少需要
O(nlogn)
时间。 If you are looking for a more efficient algorithm you could get O(n)
using hashmaps. 如果您正在寻找更高效的算法,您可以使用哈希映射获得
O(n)
。
For example with 例如用
A=[0,1,2],B=[3,0,4],C=[5,6,0]
You can loop through each list and append elements with a hash on the element. 您可以循环遍历每个列表,并在元素上添加带有哈希的元素。 The final hash will look like
最终的哈希看起来像
H = {0:[0,1,2], 1:[1], 2:[2], 3:[0], 4:[2], 5:[0], 6:[1]}
Here, the key is the element, and the value is the index in it's corresponding list. 这里,键是元素,值是其对应列表中的索引。 Now, just loop through the hashmap to find any lists that have a size of 3, in this case, to get the indices.
现在,只需循环遍历hashmap,找到大小为3的任何列表,在这种情况下,获取索引。
The code would look something like this (untested): 代码看起来像这样(未经测试):
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());
}
}
EDIT: Just noticed you suggested using retainAll() in your question. 编辑:刚刚注意到你建议在你的问题中使用retainAll()。 That would also be O(n).
那也是O(n)。
Here is a very inefficient but fairly readable solution using streams that returns you a list of lists. 这是一个非常低效但相当可读的解决方案,使用流返回列表列表。
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());
You can add toArray calls to convert to arrays if required. 如果需要,您可以添加toArray调用以转换为数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.