繁体   English   中英

从未排序的单链列表中删除重复项,从而在尝试跳过重复的元素时导致逻辑错误

[英]Remove duplicates from an unsorted singly linked list causing logical error while trying to skip the repeated element

我使用辅助数据结构“ HashSet”来解决此问题。 逻辑是我创建了一个具有非重复元素的HashSet,然后遍历链接列表中的每个节点时,检查该项目是否在hashSet中。 如果存在,我从通过链表迭代的HashSet中删除数据。 代码和逻辑错误应该很容易说明。 我只是不能跳过在main方法中创建的链表的列表中的元素。

import java.util.HashSet;

class Node{
    int value;
    Node next;

public Node(int value){
    this.value = value; 
    next = null;
}
public Node deleteNode(Node headNode){
    Node current = headNode;
    HashSet<Integer> setContainer = new HashSet<Integer>();
    while (current.next != null){
        setContainer.add(current.value);
        current = current.next;
    }
    current = headNode; // reset current to the headNode

    while (!setContainer.isEmpty()){
        if (current.next == null){
            return headNode;
        }
        if (current == headNode){
            setContainer.remove(current.value);
            current = current.next;
            //System.out.println(setContainer); Test
            continue;
        }
        if (!setContainer.contains(current.next.value)){
            current.next = current.next.next;
            current = current.next;
        }
        else{
            setContainer.remove(current.value);
            current = current.next; 
            //System.out.println(setContainer); Test
        }
    }
    return headNode;
}
public void printList(Node head){
    Node current = head;
    while(current.next != null){
        System.out.println(current.value);
        current = current.next;
    }
}}

这是主要方法

public class mainTester {
    public static void main (String[] args){        
        Node node = new Node(10);
        node.next = new Node(20);
        node.next.next = new Node(12);
        node.next.next.next = new Node(11);
        node.next.next.next.next = new Node(10);
        node.next.next.next.next.next = new Node(20);
        node.next.next.next.next.next.next = new Node(30);
        node.next.next.next.next.next.next.next = new Node(30);
        node.printList(node);
        System.out.println("\nLets see how it goes");
        node.deleteNode(node);
        node.printList(node);
    }
}

实现deleteNode之后的输出为10、20、12、11、20、30,这与预期的不同。 请帮助纠正此逻辑问题。

您逻辑中的错误是在找到重复项之后,您将跳至下一个节点,而不检查是否重复。 您可以通过更改来解决此问题

if(!setContainer.contains(node.next.value)) {

然后删除第二行

current = current.next

另外:您应该一直循环直到current == null,而不是在setContainer为空时循环,因为例如,如果同一数字在末尾重复两次,则可能会丢失重复项

这是不擦除数据的逻辑的更紧凑/更有效的版本

class Node{
    int value;
    Node next;

public Node(int value){
    this.value = value; 
    next = null;
}
public Node deleteNode(Node headNode){
    Node previous = null, current = headNode;
    HashSet<Integer> setContainer = new HashSet<Integer>();
    current = headNode; // reset current to the headNode

    while(current != null){
        if (!setContainer.contains(current.value)){
            setContainer.add(current.value);
            previous = current;
            current = current.next;
        }
        else{
            previous.next = current.next;
            current = current.next;
        }
    }
    return headNode;
}
public void printList(Node head){
    Node current = head;
    do{
        System.out.println(current.value);
        current = current.next;
    } while(current != null);
}}

它产生的输出结果为:

 Node node = new Node(10);
            node.next = new Node(20);
            node.next.next = new Node(12);
            node.next.next.next = new Node(11);
            node.next.next.next.next = new Node(10);
            node.next.next.next.next.next = new Node(20);
            node.next.next.next.next.next.next = new Node(30);
            node.next.next.next.next.next.next.next = new Node(30);
            node.next.next.next.next.next.next.next.next = new Node(20);
            node.next.next.next.next.next.next.next.next.next = new Node(30);
            node.next.next.next.next.next.next.next.next.next.next = new Node(40);
            node.printList(node);
            System.out.println("\nLets see how it goes");
            node.deleteNode(node);
            node.printList(node);

10
20
12
11
10
20
30
30
20
30
40

Lets see how it goes
10
20
12
11
30
40
private ListNode<Integer> removeDuplicate(ListNode<Integer> head) {
    Set<Integer> container = new HashSet<>();
    if (head == null) {
        return head;
    }
    ListNode<Integer> prev = head;
    ListNode<Integer> temp = head.getNext();
    while(temp != null) {
        if (container.contains(temp.getValue())) {
            prev.setNext(temp.getNext());
        } else {
            container.add(temp.getValue());
        }
    }
    return head;
}

public class ListNode<T extends Comparable<T>> {
private T value;
private ListNode<T> next;

public ListNode(T value) {
    this.value = value;
    next = null;
}

public T getValue() {
    return value;
}

public void setValue(T value) {
    this.value = value;
}

public ListNode<T> getNext() {
    return next;
}

public void setNext(ListNode<T> next) {
    this.next = next;
}
}

暂无
暂无

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

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