简体   繁体   English

删除链表中的重复项

[英]removing duplicates in linked list

I tried out the following code in java to remove duplicates from a linked list我在 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;
}

which takes the head of the linked list as input then after removing duplicates from it returns the head.它将链表的头部作为输入,然后在从中删除重复项后返回头部。

if we take the following sample input for a linked list如果我们将以下示例输入用于链表

281 386 386 957 1022 1216 1232 1364 1428 1428 1428 1428 1501 1953

it's not removing duplicates as expected它没有按预期删除重复项

I tried debugging it in vscode and was amazed to see that ptr1.data == ptr2.data evaluates to false when ptr1 is at 386 and ptr2 is at the 386 after the first 386 of the input I also tried a getter for LinkedListNode even then ptr1.getData()==ptr2.getData() was coming out false我尝试在 vscode 中对其进行调试,并且惊讶地看到ptr1.data == ptr2.data在 ptr1 为 386 且 ptr2 在输入的前 386 之后为 386 时评估为false即使那时我也尝试了 LinkedListNode 的 getter ptr1.getData()==ptr2.getData()结果是假的

is there some concept related to memory allocation I'm not getting involving heaps or something?是否有一些与 memory 分配相关的概念我没有涉及堆或其他什么?

if you're curious about the LinkedListNode class and the function used to create the linked list here they are:如果您对LinkedListNode class 和 function 用于在这里创建链接列表感到好奇,它们是:

public class LinkedListNode<T> {
T data;
LinkedListNode<T> next;
LinkedListNode (T data){
    this.data=data;
}
T getData(){
    return this.data;
}
}

and

static LinkedListNode<Integer> takeinput(){
    Scanner sc = new Scanner(System.in);
    int data = sc.nextInt();
    LinkedListNode<Integer> head = new LinkedListNode<Integer>(data);
    LinkedListNode<Integer> tail = head;
    data=sc.nextInt();
    while(data!=-1){
        LinkedListNode<Integer> newNode = new LinkedListNode<Integer>(data);
        if(head.next==null){
            head.next=newNode;
            tail=newNode;
        }else{
            tail.next=newNode;
            tail= newNode;
        }
        data=sc.nextInt();
    }
    sc.close();
    return head;   
}

input:281 386 386 957 1022 1216 1232 1364 1428 1428 1428 1428 1501 1953 -1 it stops to take input after -1 is entered and returns the head of the generated linkedlist input:281 386 386 957 1022 1216 1232 1364 1428 1428 1428 1428 1501 1953 -1 输入-1后停止接受输入并返回生成的链表的头部

This update is too late but it does not have NPE:此更新为时已晚,但它没有 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;
}

There should be 2 While loop to pick one element and check if the element exists in the Linked List .应该有2 While循环来选择一个元素并检查该element是否存在于Linked List中。 Following code may help you understand better.以下代码可以帮助您更好地理解。

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;

If I just read your title you can remove duplicates from LinkedList by iterate over, store value in a Set and check for duplicates via the Set if contains return true call remove on the integrator.如果我刚刚阅读了您的标题,您可以通过迭代从LinkedList中删除重复项,将值存储在Set中,并通过Set检查是否存在重复项,如果包含返回true ,则在积分器上调用 remove。

Iterator iter = list.iterator();
Set set = new HashSet();
while (iter.hasNext())
 {

  Object obj = iter.next();
  if(set.contains(obj))){
        iter.remove();
  }else{
        set.add(obj);
      }
  }

remove duplicate删除重复

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

Without using extra space, just iterating through the linkedlist once per node can server the purpose在不使用额外空间的情况下,只需在每个节点上遍历链表一次就可以达到目的

public void removeDupsFromLinkedList(Node head)
    {
        LinkedListImpl linkedListImpl = new LinkedListImpl();
        if(head==null)
            return;
        Node temp = head;
        while(temp!=null)
        {
            Node traverseNode = temp;
            while(traverseNode!=null)
            {
                if(traverseNode.value==temp.value && traverseNode!=temp)
                    linkedListImpl.deleteNode(traverseNode);
                traverseNode=traverseNode.next;
            }
            temp = temp.next;
        }
    }




声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM