Java 删除链接列表中的重复项

Java 删除链接列表中的重复项,java,linked-list,Java,Linked List,我在java中尝试了以下代码,以从链表中删除重复项 public static LinkedListNode<Integer> removeDuplicates(LinkedListNode<Integer> head) { LinkedListNode<Integer> ptr1=head; LinkedListNode<Integer> ptr2=head.next; if(head==null) ret

我在java中尝试了以下代码,以从链表中删除重复项

public static LinkedListNode<Integer> removeDuplicates(LinkedListNode<Integer> head) {
    LinkedListNode<Integer> ptr1=head;
    LinkedListNode<Integer> ptr2=head.next;
    if(head==null)
        return null;
    if(head.next==null)
        return head;
    while(ptr2!=null){
        if(ptr1.data==ptr2.data){
            ptr2=ptr2.next;
        }else{
            ptr1.next=ptr2;
            ptr1=ptr2;
            ptr2=ptr2.next;
        }
    }
    ptr1.next=ptr2;
    return head;
}
281 386 386 957 1022 1216 1232 1364 1428 1428 1428 1428 1501 1953
它没有按预期删除重复项

我试着在vscode中调试它,当ptr1在386,ptr2在输入的前386之后在386时,我惊奇地发现
ptr1.data==ptr2.data
的计算结果为
false
即使在那时,我也尝试了LinkedListNode的getter
ptr1.getData()==ptr2.getData()
结果为假

是否有一些与内存分配相关的概念,我没有得到涉及堆之类的东西

如果您对
LinkedListNode
类感兴趣 用于创建链接列表的函数如下:

public class LinkedListNode<T> {
T data;
LinkedListNode<T> next;
LinkedListNode (T data){
    this.data=data;
}
T getData(){
    return this.data;
}
}
公共类LinkedListNode{
T数据;
LinkedListNode下一步;
LinkedListNode(T数据){
这个。数据=数据;
}
T getData(){
返回此.data;
}
}

静态LinkedListNode takeinput(){
扫描仪sc=新的扫描仪(System.in);
int data=sc.nextInt();
LinkedListNode头=新LinkedListNode(数据);
LinkedListNode尾部=头部;
数据=sc.nextInt();
while(数据!=-1){
LinkedListNode newNode=新LinkedListNode(数据);
if(head.next==null){
head.next=newNode;
tail=newNode;
}否则{
tail.next=newNode;
tail=newNode;
}
数据=sc.nextInt();
}
sc.close();
回流头;
}
输入:281386386957102212161232136414281428 14281428 15011953-1
输入-1后,它停止接受输入,并返回生成的链接列表的标题

应该有
2,同时
循环选择一个元素并检查
链接列表中是否存在
元素
。下面的代码可以帮助您更好地理解

LinkedListNode<Integer> ptr1=head;
        LinkedListNode<Integer> ptr2=head.next;
        if(head==null)
            return null;
        if(head.next==null)
            return head;

        while (ptr1 != NULL && ptr1.next != NULL) // pick 1 element at time
        { 
            ptr2 = ptr1; 
            while (ptr2.next != NULL) 
            { 
                if (ptr1.data == ptr2.next.data) // check if the element exits in LinkedList or not
                { 
                    dup = ptr2.next; 
                    ptr2.next = ptr2.next.next; 

                } 
                else 
                    ptr2 = ptr2.next; 
            } 
            ptr1 = ptr1.next; 
        } 
        return head;
LinkedListNode ptr1=头;
LinkedListNode ptr2=head.next;
if(head==null)
返回null;
if(head.next==null)
回流头;
while(ptr1!=NULL&&ptr1.next!=NULL)//每次选择1个元素
{ 
ptr2=ptr1;
while(ptr2.next!=NULL)
{ 
if(ptr1.data==ptr2.next.data)//检查元素是否存在于LinkedList中
{ 
dup=ptr2.next;
ptr2.next=ptr2.next.next;
} 
其他的
ptr2=ptr2.next;
} 
ptr1=ptr1.next;
} 
回流头;

如果我刚刚阅读了您的标题,您可以通过迭代从
链接列表中删除重复项,将值存储在
集合中
并通过
集合
检查重复项,如果包含return
true
调用integrator上的remove

Iterator iter=list.Iterator();
Set=newhashset();
while(iter.hasNext())
{
Object obj=iter.next();
if(set.contains(obj))){
iter.remove();
}否则{
集合。添加(obj);
}
}
删除重复项

list.stream().distinct().peek(System.out::println).collect(Collectors.toList());

此更新太晚,但没有NPE:

public static LinkedListNode<Integer> removeDuplicates(LinkedListNode<Integer> head) {
    if (head == null || head.next == null)
        return head;

    LinkedListNode<Integer> ptr1 = head;
    LinkedListNode<Integer> ptr2 = head.next;

    while (ptr2 != null) {
        while(ptr1.data.equals(ptr2.data)) {
            ptr2 = ptr2.next;
            ptr1.next = ptr2;
        }
        ptr1.next = ptr2;
        ptr1 = ptr2;
        ptr2 = ptr2.next;

    }
    ptr1.next = ptr2;
    return head;
}
移除的公共静态LinkedListNode副本(LinkedListNode头){
if(head==null | | head.next==null)
回流头;
LinkedListNode ptr1=头;
LinkedListNode ptr2=head.next;
while(ptr2!=null){
while(ptr1.data.equals(ptr2.data)){
ptr2=ptr2.next;
ptr1.next=ptr2;
}
ptr1.next=ptr2;
ptr1=ptr2;
ptr2=ptr2.next;
}
ptr1.next=ptr2;
回流头;
}

您知道Java中
==
equals()
之间的区别吗<代码>=
测试身份,你的副本可能是相等的,但它们永远不会相同——正如你的程序清楚地指出的那样。删除副本的最简单方法是将所有内容放入一个集合,然后将该集合放入一个链接列表。谢谢@tquadrat这就是问题所在,现在它工作正常,我忘了整数对象部分,这能回答你的问题吗?谢谢你的回答我忘了提到有O(1)空间复杂度的要求你的答案是最好的,否则这个代码
ptr1.data==ptr2.next->data
看起来不是Java:)@AlexRudenko谢谢你指出错误。这是在C++中完成的,还有一个小问题:OP的列表没有从集合框架中实现
,并且没有类似的stream()(ツ) _ / ¯
public static LinkedListNode<Integer> removeDuplicates(LinkedListNode<Integer> head) {
    if (head == null || head.next == null)
        return head;

    LinkedListNode<Integer> ptr1 = head;
    LinkedListNode<Integer> ptr2 = head.next;

    while (ptr2 != null) {
        while(ptr1.data.equals(ptr2.data)) {
            ptr2 = ptr2.next;
            ptr1.next = ptr2;
        }
        ptr1.next = ptr2;
        ptr1 = ptr2;
        ptr2 = ptr2.next;

    }
    ptr1.next = ptr2;
    return head;
}