在linkedlist of String中查找重复项的最有效方法-java
假设我们有一个linkedlist of linkedlist of String在linkedlist of String中查找重复项的最有效方法-java,java,linked-list,duplicates,Java,Linked List,Duplicates,假设我们有一个linkedlist of linkedlist of String LinkedList<LinkedList<String>> lls = new LinkedList<LinkedList<String>> (); LinkedList<String> list1 = new LinkedList<String>(Arrays.asList("dog", "cat", "snake")); LinkedL
LinkedList<LinkedList<String>> lls = new LinkedList<LinkedList<String>> ();
LinkedList<String> list1 = new LinkedList<String>(Arrays.asList("dog", "cat", "snake"));
LinkedList<String> list2 = new LinkedList<String>(Arrays.asList("donkey", "fox", "dog"));
LinkedList<String> list3 = new LinkedList<String>(Arrays.asList("horse", "cat", "pig"));
lls.add(list1);
lls.add(list2);
lls.add(list3);
LinkedList lls=newlinkedlist();
LinkedList list1=新的LinkedList(Arrays.asList(“狗”、“猫”、“蛇”));
LinkedList list2=新的LinkedList(Arrays.asList(“驴子”、“狐狸”、“狗”));
LinkedList list3=新的LinkedList(Arrays.asList(“horse”、“cat”、“pig”));
lls.add(列表1);
lls.add(列表2);
lls.add(清单3);
如您所见,这3个linkedlist的字符串是不同的,但也有一些共同的元素。
我的目标是编写一个函数,将每个列表和其他列表进行比较,如果至少有一个相同的元素(dog在list1和list2中),则返回TRUE,否则返回FALSE
我认为我需要做的第一件事是比较列表中所有可能的排列,列表之间的比较是逐元素的。
我不确定这是最有效的方法。
您能提出一个最终最有效的想法吗?将所有列表中的所有项目添加到一个列表中,然后对其进行排序(
Collections.sort
)。然后遍历它并检查重复项
例如
ArrayList list=new ArrayList();
list.addAll(列表1);//再加上其他的
集合。排序(列表);
用于(字符串s:列表){
如果(该项与上一项相同){
返回true;
}
}
将所有列表中的所有项目添加到一个列表中,然后对其进行排序(Collections.sort
)。然后遍历它并检查重复项
例如
ArrayList list=new ArrayList();
list.addAll(列表1);//再加上其他的
集合。排序(列表);
用于(字符串s:列表){
如果(该项与上一项相同){
返回true;
}
}
使用retainal()
for(最终链接列表ll:lls)
{
清单1.保留(ll);
}
System.out.println(“list1=“+list1”);
使用retainal()
for(最终链接列表ll:lls)
{
清单1.保留(ll);
}
System.out.println(“list1=“+list1”);
LinkedList不是检测重复项的最佳集合。若可以,试着使用HashSet,但若不能做到这一点,仍然可以将列表中的所有元素放到一个集合中。哈希集包含没有重复项的元素,因此,如果列表大小中存在重复的元素,哈希集包含的元素将少于所有列表。LinkedList不是检测重复项的最佳集合。若可以,试着使用HashSet,但若不能做到这一点,仍然可以将列表中的所有元素放到一个集合中。Hashset包含没有重复项的元素,因此如果列表大小中有重复的元素,Hashset的元素将比所有列表包含的元素都少。假设给定的列表不应通过删除元素或对其排序(顺便说一句,其复杂性为O(nlogn))来更改,您基本上需要一个函数作为“构建块”对于实际的解决方案。即,检查一个集合是否包含另一个集合中包含的任何元素的函数
当然,这可以通过在第二个集合上使用Collection#contains
来解决。但是对于某些集合(特别是列表),这有O(n),并且检查的总运行时间将是O(n*n)
为了避免这种情况,您可以创建一个包含第二个集合的所有元素的集合。对于集合
,包含
方法保证为O(1)
然后,使用Stream#anyMatch
,可以方便地进行实际检查:
containing.stream().anyMatch(e -> set.contains(e))
所以完整的例子可以是
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class DuplicatesInLinkedLists
{
public static void main(String[] args)
{
LinkedList<LinkedList<String>> lls =
new LinkedList<LinkedList<String>>();
LinkedList<String> list1 =
new LinkedList<String>(Arrays.asList("dog", "cat", "snake"));
LinkedList<String> list2 =
new LinkedList<String>(Arrays.asList("donkey", "fox", "dog"));
LinkedList<String> list3 =
new LinkedList<String>(Arrays.asList("horse", "cat", "pig"));
lls.add(list1);
lls.add(list2);
lls.add(list3);
checkDuplicates(lls);
}
private static void checkDuplicates(
List<? extends Collection<?>> collections)
{
for (int i = 0; i < collections.size(); i++)
{
for (int j = i + 1; j < collections.size(); j++)
{
Collection<?> ci = collections.get(i);
Collection<?> cj = collections.get(j);
boolean b = containsAny(ci, cj);
System.out.println(
"Collection " + ci + " contains any of " + cj + ": " + b);
}
}
}
private static boolean containsAny(Collection<?> containing,
Collection<?> contained)
{
Set<Object> set = new LinkedHashSet<Object>(contained);
return containing.stream().anyMatch(e -> set.contains(e));
}
}
如果列表中的元素对我来说是可修改的,那么你可以写
lists.add(new ArrayList<String>(Arrays.asList("dog", "cat", "snake"));
lists.add(新的ArrayList(Arrays.asList(“dog”、“cat”、“snake”));
或者,类似地,使用LinkedList
而不是ArrayList
,但是对于这个略图化的用例,我无法想象为什么会有强烈的理由故意使用LinkedList
。假设给定的列表不应该通过删除元素或对它们进行排序(其中有O(nlogn))来更改顺便说一句,复杂度),您基本上需要一个函数作为实际解决方案的“构建块”,即检查一个集合是否包含另一个集合中包含的任何元素的函数
当然,这可以通过对第二个集合使用Collection#contains
来解决。但是对于某些集合(尤其是列表),这有O(n),并且检查的总运行时间为O(n*n)
为了避免这种情况,您可以创建一个包含第二个集合的所有元素的Set
。对于Set
,contains
方法保证为O(1)
然后,使用Stream#anyMatch
,可以方便地进行实际检查:
containing.stream().anyMatch(e -> set.contains(e))
所以完整的例子可以是
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class DuplicatesInLinkedLists
{
public static void main(String[] args)
{
LinkedList<LinkedList<String>> lls =
new LinkedList<LinkedList<String>>();
LinkedList<String> list1 =
new LinkedList<String>(Arrays.asList("dog", "cat", "snake"));
LinkedList<String> list2 =
new LinkedList<String>(Arrays.asList("donkey", "fox", "dog"));
LinkedList<String> list3 =
new LinkedList<String>(Arrays.asList("horse", "cat", "pig"));
lls.add(list1);
lls.add(list2);
lls.add(list3);
checkDuplicates(lls);
}
private static void checkDuplicates(
List<? extends Collection<?>> collections)
{
for (int i = 0; i < collections.size(); i++)
{
for (int j = i + 1; j < collections.size(); j++)
{
Collection<?> ci = collections.get(i);
Collection<?> cj = collections.get(j);
boolean b = containsAny(ci, cj);
System.out.println(
"Collection " + ci + " contains any of " + cj + ": " + b);
}
}
}
private static boolean containsAny(Collection<?> containing,
Collection<?> contained)
{
Set<Object> set = new LinkedHashSet<Object>(contained);
return containing.stream().anyMatch(e -> set.contains(e));
}
}
如果列表中的元素对我来说是可修改的,那么你可以写
lists.add(new ArrayList<String>(Arrays.asList("dog", "cat", "snake"));
lists.add(新的ArrayList(Arrays.asList(“dog”、“cat”、“snake”));
或者,类似地,使用LinkedList
而不是ArrayList
,但是对于这个略图化的用例,我无法想象为什么会有强烈的理由故意使用LinkedList
。假设您想要使用LinkedList并且不允许转换到另一个数据结构,那么您可以做的就是创建一个me接受可变数量的链接列表的方法。从那里您希望获取所有唯一的链接列表组合,然后比较这些链接列表之间的所有唯一元素,如果您发现一个公共元素,请将该对链接列表标记为公共。您希望如何跟踪/返回数据(例如,一组具有共同元素的linkedlist对)取决于输出的外观,但这是我将使用的代码的一般结构。假设您希望使用linkedlist,并且不允许转换为其他数据类型