删除重复链接列表Java

时间:2015-10-22 15:09:24

标签: java linked-list

我正在尝试实现一个删除链表中所有重复项的方法。我设法照顾尾巴。换句话说,如果尾部data是重复的,程序就不会抛出exception error。现在,我试图照顾头部,如果head的数据是重复的,我想设置head = head.next所以副本不再在链表中。但是,我的方法deleteDuplicates无法处理head。有人建议解决这个问题吗?

class Node {
        private Node next = null; 
        private int data; 

        public Node(int d) {
            data = d; 
        }

        void appendToTail(int d) {
            Node end = new Node(d); 
            Node n = this; 

            while(n.next != null) {
                n = n.next; 
            }
            n.next = end; 
        }

        void print() {
            Node n = this; 
            while(n != null) {
                System.out.println(n.data); 
                n = n.next; 
            }
        }

        Node deleteDuplicates(Node head, int d) {
            Node n = head;
            if(n.data == d) {
                head = head.next; 
                n = n.next; 
            }
            while(n != null) {
                if(n.next.data == d) {
                    if(n.next == null && n.next.data == d) {
                        return head;
                    }
                    n.next = n.next.next;
                }
                n = n.next; 
            }
            return head; 
        }

        public static void main(String [] args) {
            Node x = new Node(9); 
            x.appendToTail(5);
            x.appendToTail(9);
            x.appendToTail(6);
            x.appendToTail(9);  
            x.appendToTail(7);
            x.appendToTail(9);  
            x.appendToTail(8); 
            x.appendToTail(9); 
            x.deleteDuplicates(x, 9); 
            x.print(); 
        }   
    }

5 个答案:

答案 0 :(得分:1)

您的代码中的问题是您在删除后没有重新分配头部。 如果您按如下方式修改它,我认为您的头部删除问题将得到解决。

x = x.deleteDuplicates(x, 9);

毋庸置疑,还有其他有效的方法,如散列,可用于降低代码的时间复杂度。

答案 1 :(得分:1)

只要符合值,您就想继续移除头部。因此,将if替换为while

Node n = head;
while (n != null && n.data == d) {
    n = n.next; 
}
head = n;

你也有其他问题。例如,当n.next为空时,此行将引发空指针异常:

if(n.next == null && n.next.data == d) {

修复你的while循环:

while (n.next != null) {
    if (n.next.data == d) {
        n.next = n.next.next;
    } else {
        n = n.next;
    }
}

最后,您选择的方法名称非常具有误导性。 " deleteDuplicates"建议删除所有重复项, 例如:

from: 9->5->6->9->7->9->8->9  
  to: 9->5->6->7->8

将此方法称为delete

是有意义的

把它放在一起

应用上述修正后,方法变为:

Node delete(Node head, int d) {
    Node n = head;

    // skip consecutive d values at head
    while (n != null && n.data == d) {
        n = n.next; 
    }
    head = n;

    // skip d values
    while (n.next != null) {
        if (n.next.data == d) {
            n.next = n.next.next;
        } else {
            n = n.next;
        }
    }

    return head;
}

答案 2 :(得分:0)

如果您只需要一个唯一对象的容器,最好的方法是让这些对象实现.equals()和.hashCode()方法,这样您就可以使用Set来处理唯一性逻辑。

平等可以轻松实现,作为所有课程的补充。字段相等,以及来自所有类的串联的散列的hashCode'字段hashCodes。

如果您因某些原因需要将它们关联起来,LinkedHashSet就适合您。

整数示例:

LinkedHashSet<Integer> myCollection = new LinkedHashSet<Integer>();
myCollection.add(5);
myCollection.add(3);
myCollection.add(2);
myCollection.add(5);
myCollection.add(2);
System.out.println(myCollection);
// prints [5, 3, 2]

可以找到自定义类的示例here

答案 3 :(得分:0)

通过运行代码验证。您的代码应如下所示:

x.deleteDuplicates(x, 9).print();

然后删除方法应为:

Node deleteDuplicates(Node head, int d) {
    Node nextNode=head;
    if(head.data == d) {
        if(head.next==null) {
            return null;
        }
         return deleteDuplicates(head.next, d);
    }
    Node previous=head;
    while(nextNode.next != null) {
        nextNode=nextNode.next;
        if(nextNode.data == d) {
            previous.next=nextNode.next;
        }
        previous=nextNode;
    }
    return head;
}

输出:

5
6
7
8

在检查是否需要删除头节点时,将下一个节点作为头节点。您还要检查是否要删除最后一个节点,然后将下一个节点作为空。

答案 4 :(得分:0)

类似(未经测试的代码):

这个想法是,对于每个元素,遍历列表的其余部分并删除和复制当前元素

public void deleteDupes(Node head) {
  if (head == null || head.next == null) {
    return;
  }
  Node current = head;
  while (current != null) {
    Node runner = head;
    while (runner.next != null) {
      if (runner.next.val == current.val) {
        runner.next = runner.next.next;
      }
      else {
        runner = runner.next;
      }
    }
    current = current.next;
  }
}