在链接的字符串列表的链表中查找重复项的最有效方法 - java

时间:2017-01-25 15:18:19

标签: java linked-list duplicates

让我们假设我们有一个链表的链表。

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);

正如您所看到的,这3个字符串链接列表是不同的,但也有一些共同的元素。 我的目标是编写一个函数,将每个列表与其他列表进行比较,如果至少有一个共同的元素(dog在list1和list2中),则返回TRUE,否则返回FALSE。

我认为我需要的第一件事就是比较列表中所有可能的排列,列表之间的比较是逐个元素的。 我不确定这是最有效的方法。 你能提出一个最有效的想法吗?

5 个答案:

答案 0 :(得分:2)

假设不应该通过删除元素或对它们进行排序来更改给定列表(顺便说一下,它具有O(nlogn)复杂度),您基本上需要一个函数作为实际解决方案的“构建块”。即,一个函数,用于检查一个集合是否包含另一个集合中包含的任何元素。

当然,这可以通过在第二个集合上使用Collection#contains来解决。但对于某些集合(特别是列表),它有O(n),检查的总运行时间为O(n * n)。

为避免这种情况,您可以创建一个包含第二个集合的所有元素的Set。对于Setcontains方法保证为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));
    }
}

附注:您发布的代码几乎肯定在当前表单中没有意义。列表的声明和创建通常应该依赖于List

List<List<String>> lists = new ArrayList<List<String>>();
lists.add(Arrays.asList("dog", "cat", "snake");
...

如果列表中的元素必须是可修改的,那么你可以写

lists.add(new ArrayList<String>(Arrays.asList("dog", "cat", "snake"));

或者,类似地,使用LinkedList代替ArrayList,但对于草拟的用例,我无法想象为什么应该有充分理由故意使用LinkedList ...

答案 1 :(得分:0)

将所有列表中的所有项目添加到一个列表中,然后对其进行排序(Collections.sort)。然后迭代它并检查重复。

E.g。

ArrayList<String> list = new ArrayList<>();
list.addAll(list1); // Add the others as well
Collections.Sort(list);
for (String s : list) {
    If (the item is the same as the previous item) {
        return true;
    }
}

答案 2 :(得分:0)

使用retainAll()

01-25 15:29:09.739 2594-2594/? D/dalvikvm: Not late-enabling CheckJNI (already on)
01-25 15:29:09.739 2594-2594/? E/Trace: error opening trace file: Permission denied (13)
01-25 15:29:09.749 2594-2594/? I/dalvikvm: Could not find method android.app.Application.registerOnProvideAssistDataListener, referenced from method com.android.tools.fd.runtime.BootstrapApplication.registerOnProvideAssistDataListener
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 231: Landroid/app/Application;.registerOnProvideAssistDataListener (Landroid/app/Application$OnProvideAssistDataListener;)V
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
01-25 15:29:09.749 2594-2594/? I/dalvikvm: Could not find method android.app.Application.unregisterOnProvideAssistDataListener, referenced from method com.android.tools.fd.runtime.BootstrapApplication.unregisterOnProvideAssistDataListener
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 234: Landroid/app/Application;.unregisterOnProvideAssistDataListener (Landroid/app/Application$OnProvideAssistDataListener;)V
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
01-25 15:29:09.749 2594-2594/? I/InstantRun: Instant Run Runtime started. Android package is org.enotboris.dayz, real application class is null.
01-25 15:29:09.749 2594-2594/? W/InstantRun: No instant run dex files added to classpath

                                             [ 01-25 15:29:09.749  1418: 1526 D/         ]
                                             HostConnection::get() New Host Connection established 0xb8b397b0, tid 1526
01-25 15:29:09.749 2594-2594/? E/dalvikvm: Could not find class 'android.util.ArrayMap', referenced from method com.android.tools.fd.runtime.MonkeyPatcher.monkeyPatchExistingResources
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve check-cast 1926 (Landroid/util/ArrayMap;) in Lcom/android/tools/fd/runtime/MonkeyPatcher;
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x1f at 0x025e
01-25 15:29:09.749 2594-2594/? E/dalvikvm: Could not find class 'android.util.ArrayMap', referenced from method com.android.tools.fd.runtime.MonkeyPatcher.pruneResourceCache
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve const-class 1926 (Landroid/util/ArrayMap;) in Lcom/android/tools/fd/runtime/MonkeyPatcher;
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x1c at 0x0060
01-25 15:29:09.749 2594-2594/? I/dalvikvm: Could not find method android.view.Window$Callback.onProvideKeyboardShortcuts, referenced from method android.support.v7.view.WindowCallbackWrapper.onProvideKeyboardShortcuts
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve interface method 16445: Landroid/view/Window$Callback;.onProvideKeyboardShortcuts (Ljava/util/List;Landroid/view/Menu;I)V
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x72 at 0x0002
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to find class referenced in signature (Landroid/view/SearchEvent;)
01-25 15:29:09.749 2594-2594/? I/dalvikvm: Could not find method android.view.Window$Callback.onSearchRequested, referenced from method android.support.v7.view.WindowCallbackWrapper.onSearchRequested
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve interface method 16447: Landroid/view/Window$Callback;.onSearchRequested (Landroid/view/SearchEvent;)Z
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x72 at 0x0002
01-25 15:29:09.749 2594-2594/? I/dalvikvm: Could not find method android.view.Window$Callback.onWindowStartingActionMode, referenced from method android.support.v7.view.WindowCallbackWrapper.onWindowStartingActionMode
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve interface method 16451: Landroid/view/Window$Callback;.onWindowStartingActionMode (Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode;
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x72 at 0x0002
01-25 15:29:09.749 2594-2594/? I/dalvikvm: Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.widget.TintTypedArray.getChangingConfigurations
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 673: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
01-25 15:29:09.749 2594-2594/? I/dalvikvm: Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.widget.TintTypedArray.getType
01-25 15:29:09.749 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 695: Landroid/content/res/TypedArray;.getType (I)I
01-25 15:29:09.749 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0008
01-25 15:29:09.759 2594-2594/? I/dalvikvm: Could not find method android.support.graphics.drawable.VectorDrawableCompat.getLayoutDirection, referenced from method android.support.graphics.drawable.VectorDrawableCompat.needMirroring
01-25 15:29:09.759 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 1746: Landroid/support/graphics/drawable/VectorDrawableCompat;.getLayoutDirection ()I
01-25 15:29:09.759 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x000f
01-25 15:29:09.759 2594-2594/? I/dalvikvm: Could not find method android.view.ViewGroup.onRtlPropertiesChanged, referenced from method android.support.v7.widget.Toolbar.onRtlPropertiesChanged
01-25 15:29:09.759 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 16344: Landroid/view/ViewGroup;.onRtlPropertiesChanged (I)V
01-25 15:29:09.759 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6f at 0x0007
01-25 15:29:09.759 2594-2594/? I/dalvikvm: Could not find method android.content.Context.getColorStateList, referenced from method android.support.v7.content.res.AppCompatResources.getColorStateList
01-25 15:29:09.759 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 417: Landroid/content/Context;.getColorStateList (I)Landroid/content/res/ColorStateList;
01-25 15:29:09.759 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0006
01-25 15:29:09.769 2594-2594/? I/dalvikvm: Could not find method android.content.res.Resources.getDrawable, referenced from method android.support.v7.widget.ResourcesWrapper.getDrawable
01-25 15:29:09.769 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 636: Landroid/content/res/Resources;.getDrawable (ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
01-25 15:29:09.769 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
01-25 15:29:09.769 2594-2594/? I/dalvikvm: Could not find method android.content.res.Resources.getDrawableForDensity, referenced from method android.support.v7.widget.ResourcesWrapper.getDrawableForDensity
01-25 15:29:09.769 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 638: Landroid/content/res/Resources;.getDrawableForDensity (IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
01-25 15:29:09.769 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0002
01-25 15:29:09.779 2594-2598/? D/dalvikvm: GC_CONCURRENT freed 261K, 4% free 10877K/11271K, paused 0ms+12ms, total 15ms
01-25 15:29:09.779 2594-2594/? E/dalvikvm: Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
01-25 15:29:09.779 2594-2594/? W/dalvikvm: VFY: unable to resolve instanceof 153 (Landroid/graphics/drawable/RippleDrawable;) in Landroid/support/v7/widget/AppCompatImageHelper;
01-25 15:29:09.779 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x20 at 0x000c
01-25 15:29:09.779 2594-2594/? I/dalvikvm: Could not find method android.support.v4.widget.DrawerLayout$LayoutParams.setMarginEnd, referenced from method com.mikepenz.materialdrawer.Drawer.processDrawerLayoutParams
01-25 15:29:09.779 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 10374: Landroid/support/v4/widget/DrawerLayout$LayoutParams;.setMarginEnd (I)V
01-25 15:29:09.779 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0021
01-25 15:29:09.789 2594-2594/? I/dalvikvm: Could not find method android.support.v4.widget.DrawerLayout$LayoutParams.setMarginEnd, referenced from method com.mikepenz.materialdrawer.Drawer.processDrawerLayoutParams
01-25 15:29:09.789 2594-2594/? W/dalvikvm: VFY: unable to resolve virtual method 10374: Landroid/support/v4/widget/DrawerLayout$LayoutParams;.setMarginEnd (I)V
01-25 15:29:09.789 2594-2594/? D/dalvikvm: VFY: replacing opcode 0x6e at 0x0042
01-25 15:29:09.789 2594-2594/? D/dalvikvm: GC_FOR_ALLOC freed 25K, 4% free 10907K/11271K, paused 2ms, total 2ms
01-25 15:29:09.789 2594-2594/? I/dalvikvm-heap: Grow heap (frag case) to 11.286MB for 589836-byte allocation
01-25 15:29:09.799 2594-2598/? D/dalvikvm: GC_CONCURRENT freed 2K, 4% free 11480K/11911K, paused 11ms+0ms, total 12ms
01-25 15:29:09.809 2594-2594/? D/dalvikvm: GC_FOR_ALLOC freed <1K, 4% free 11480K/11911K, paused 3ms, total 3ms
01-25 15:29:09.809 2594-2594/? I/dalvikvm-heap: Grow heap (frag case) to 13.534MB for 2359308-byte allocation
01-25 15:29:09.819 2594-2598/? D/dalvikvm: GC_CONCURRENT freed 0K, 4% free 13784K/14279K, paused 11ms+0ms, total 12ms
01-25 15:29:09.869 2594-2594/? D/libEGL: loaded /system/lib/egl/libEGL_emulation.so
01-25 15:29:09.869 2594-2594/? D/libEGL: loaded /system/lib/egl/libGLESv1_CM_emulation.so
01-25 15:29:09.869 2594-2594/? D/libEGL: loaded /system/lib/egl/libGLESv2_emulation.so

                                         [ 01-25 15:29:09.869  2594: 2594 D/         ]
                                         HostConnection::get() New Host Connection established 0xb893e0e8, tid 2594
01-25 15:29:09.879 2594-2594/? W/gralloc_ranchu: Gralloc pipe failed
01-25 15:29:09.889 2594-2594/? D/OpenGLRenderer: Enabling debug mode 0
01-25 15:29:09.889 2594-2594/? D/AndroidRuntime: Shutting down VM
01-25 15:29:09.889 2594-2594/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa6623228)
01-25 15:29:09.899 2594-2594/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 java.lang.RuntimeException: The font for the given icon isn't registered!
                                                     at com.mikepenz.iconics.IconicsDrawable.icon(IconicsDrawable.java:121)
                                                     at com.mikepenz.iconics.IconicsDrawable.<init>(IconicsDrawable.java:89)
                                                     at com.mikepenz.materialdrawer.model.PrimaryDrawerItem.convertView(PrimaryDrawerItem.java:190)
                                                     at com.mikepenz.materialdrawer.adapter.DrawerAdapter.getView(DrawerAdapter.java:125)
                                                     at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
                                                     at android.widget.AbsListView.obtainView(AbsListView.java:2271)
                                                     at android.widget.ListView.makeAndAddView(ListView.java:1769)
                                                     at android.widget.ListView.fillDown(ListView.java:672)
                                                     at android.widget.ListView.fillSpecific(ListView.java:1330)
                                                     at android.widget.ListView.layoutChildren(ListView.java:1612)
                                                     at android.widget.AbsListView.onLayout(AbsListView.java:2106)
                                                     at android.view.View.layout(View.java:13754)
                                                     at android.view.ViewGroup.layout(ViewGroup.java:4364)
                                                     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
                                                     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
                                                     at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
                                                     at android.view.View.layout(View.java:13754)
                                                     at android.view.ViewGroup.layout(ViewGroup.java:4364)
                                                     at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1217)
                                                     at android.view.View.layout(View.java:13754)
                                                     at android.view.ViewGroup.layout(ViewGroup.java:4364)
                                                     at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
                                                     at android.view.View.layout(View.java:13754)
                                                     at android.view.ViewGroup.layout(ViewGroup.java:4364)
                                                     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
                                                     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
                                                     at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
                                                     at android.view.View.layout(View.java:13754)
                                                     at android.view.ViewGroup.layout(ViewGroup.java:4364)
                                                     at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
                                                     at android.view.View.layout(View.java:13754)
                                                     at android.view.ViewGroup.layout(ViewGroup.java:4364)
                                                     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
                                                     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
                                                     at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
                                                     at android.view.View.layout(View.java:13754)
                                                     at android.view.ViewGroup.layout(ViewGroup.java:4364)
                                                     at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
                                                     at android.view.View.layout(View.java:13754)
                                                     at android.view.ViewGroup.layout(ViewGroup.java:4364)
                                                     at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1868)
                                                     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1689)
                                                     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
                                                     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
                                                     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
                                                     at android.view.Choreographer.doCallbacks(Choreographer.java:555)
                                                     at android.view.Choreographer.doFrame(Choreographer.java:525)
                                                     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
                                                     at android.os.Handler.handleCallback(Handler.java:615)
                                                     at android.os.Handler.dispatchMessage(Handler.java:92)
                                                     at android.os.Looper.loop(Looper.java:137)
                                                     at android.app.ActivityThread.main(ActivityThread.java:4745)
                                                     at java.lang.reflect.Method.invokeNative(Native Method)
                                                     at java.lang.reflect.Method.invoke(Method.java:511)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                     at dalvik.system.NativeStart.main(Native Method)

答案 3 :(得分:0)

LinkedList不是重复检测的最佳集合。如果可以的话,尝试使用HashSet,但是如果你不能这样做,你仍然可以将列表中的所有元素都设置好。 Hashset包含没有重复的元素,因此如果列表中的重复元素hashset将包含比所有列表更少的元素。

答案 4 :(得分:0)

假设您要使用LinkedLists并且不允许转换为其他数据结构,您可以做的是创建一个接受可变数量的LinkedLists的方法。从那里你想要获取LinkedLists的所有独特组合,然后比较这些链接列表之间的所有唯一元素,如果你发现一个公共元素标记这对链接列表是常见的。您希望如何跟踪/返回数据(例如,具有共同元素的链表对的集合)取决于您的输出应该是什么样的,但这是我将使用的代码的一般结构。 / p>