Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在O(n)中的两个链表之间查找缺少的元素?_Java_Linked List_Difference - Fatal编程技术网

Java 如何在O(n)中的两个链表之间查找缺少的元素?

Java 如何在O(n)中的两个链表之间查找缺少的元素?,java,linked-list,difference,Java,Linked List,Difference,我有两个单独的整数链表。其中一个是另一个的子集(数字的顺序不同)。查找第一个列表中不包含而第二个列表中不包含的数字的最佳方法(关于性能)是什么 我的想法是首先对它们进行排序(使用合并排序),然后逐个元素进行比较。 因此,它需要O(nlogn+mlogm+n),但是应该存在一个更好的O(n)解决方案。您可以将它们放在不同的映射中,然后比较它们。对于m&n循环,放入映射应该是2个单循环,映射的查找时间是1。在这种情况下,哈希集是最好的数据结构。 使用此代码,您可以在O(n)中实现结果。 如果你有更多

我有两个单独的整数链表。其中一个是另一个的子集(数字的顺序不同)。查找第一个列表中不包含而第二个列表中不包含的数字的最佳方法(关于性能)是什么

我的想法是首先对它们进行排序(使用合并排序),然后逐个元素进行比较。
因此,它需要
O(nlogn+mlogm+n)
,但是应该存在一个更好的
O(n)
解决方案。

您可以将它们放在不同的映射中,然后比较它们。对于m&n循环,放入映射应该是2个单循环,映射的查找时间是1。

在这种情况下,哈希集是最好的数据结构。 使用此代码,您可以在O(n)中实现结果。 如果你有更多的条件,请告诉我,我可以提出相应的建议

 public class LinkedList {

        private ListNode head;

        public ListNode getHead() {
            return head;
        }
    }

    public class ListNode {

        public int value;
        public ListNode next;

        ListNode(int value) {
            this.value = value;
        }
    }

    public class UtilClass{
       public static int checkLists(LinkedList list1, LinkedList list){
            ListNode head = myList2.getHead();

            HashSet<Integer> hashSet = new HashSet<Integer>();

            while(head!=null){
                hashSet.add(head.value);
                head = head.next;
            }

            head = myList.getHead();

            while(head!=null){
                boolean b = hashSet.add(head.value);
                if(b == true) return head.value;
                head = head.next;
            }
             return -1111;
    }
    }
公共类链接列表{
私有节点头;
公共ListNode getHead(){
回流头;
}
}
公共类列表节点{
公共价值观;
公共列表节点下一步;
ListNode(int值){
这个值=值;
}
}
公共类UtilClass{
公共静态int检查列表(LinkedList列表1,LinkedList列表){
ListNode head=myList2.getHead();
HashSet HashSet=新的HashSet();
while(head!=null){
hashSet.add(head.value);
head=head.next;
}
head=myList.getHead();
while(head!=null){
布尔b=hashSet.add(head.value);
如果(b==true),则返回head.value;
head=head.next;
}
返回-1111;
}
}

您可以使用removeAll方法。您只需创建一个方法,该方法接受两个列表,一个是原始列表,另一个是子列表,然后返回缺少元素的列表:

List getMissing(List original, List sub){
     original.removeAll(sub);
     return original;
}
不过,这是以二次时间运行的

如果您真的想强制它在线性时间O(n)中运行,那么您必须编写自定义类来包装您的输入,这样对于每个输入,都有一个标志来监视它是否已添加到子列表中。您还可以设计一个类,在监视两个列表的内容的同时方便添加和删除元素。

这在时间和空间上都是O(n)解决方案

逻辑

假设原始链表的大小为N,我们称之为
LL1
,第二个链表为
LL2

=>准备一个大小为N的
Hasmap
键将是
LL1
中的
数字,而
值将是
LL2
中的频率

 HashMap<Integer,Integer> map= new HashMap<Integer,Integer>();
for (map.Entry<Integer,Integer> entry : map.entrySet())
{
    if(entry.getValue() == 0)
        System.out.println(entry.getKey());//This is a loner
}
=>现在开始在
LL2
中循环,选择数字作为键,在迭代
LL2
中的所有值时,将值增加
1

,您在
LL1
LL1
中都有所有公共数字,它们位于
HashMap
内部,具有
frequency>0

  map.put(key, map.get(key) + 1);
=>现在开始遍历
hasmap
,搜索
值=0
,找到后,打印
,因为该数字仅出现在
LL1
中,而不出现在
LL2

 HashMap<Integer,Integer> map= new HashMap<Integer,Integer>();
for (map.Entry<Integer,Integer> entry : map.entrySet())
{
    if(entry.getValue() == 0)
        System.out.println(entry.getKey());//This is a loner
}
for(map.Entry:map.entrySet())
{
if(entry.getValue()==0)
System.out.println(entry.getKey());//这是一个孤独的人
}
2次迭代和O(n)内存以及O(n)时间。

设n=m+n

  • 添加列表。因为它们是链表,所以这是廉价的O(1)
  • 对它们进行排序O(N log N)-最好使用ArrayList
  • 沿着列表走一走,如果没有找到一个连续的对{x,x},你就找到了一个缺失的对,O(N), 因为第二个列表是一个子集
所以O(N.logn)

由于列表没有排序,因此任何加速都包括排序之类的内容,这会产生成本。所以O(N.logn)是好的

如果您想要O(N)可以按如下方式操作(简化,使用正数):

这是用记忆和时间来交换的。请注意,这个答案可能不被接受,因为内存是2MAX_值初始化/清除它也需要时间

可能的

最明智的答案可能是(准)协同排序两个列表。并在排序过程中检测缺失的元素。比如选择一个随意的“中位数”元素,移动索引来分割列表,然后分而治之

如果列表大小相差1

然后,您只需要对每个列表求和,差就是缺少的值:O(N)。
用于溢出。

只需要一个映射/集:用第一个列表的内容填充它,然后在迭代第二个列表时探测它。请提供一些代码片段。请随意编辑答案。更好的解决方案是不要使用链表来表示集合。使用
集合
@Gene OP可能需要保持顺序(因为他/她提到的顺序是不同的),尽管在这里使用集合可能有用。对于两个小列表,O(n*m)暴力可能是“最快的”。。我想这些序列的规模很大,但请记住找到并关注实际的瓶颈。@user2864740那么他应该使用
LinkedHashSet
@这可能是另一种可能性。然而,我不知道代码使用了什么(其他)算法,比如一个排序链表。