[英]Remove Duplicates from Linked List
所以我有一个链接列表,我试图从中删除重复项。
我想到的基本算法是几乎使用跑步者技术。 我保留两个指针来比较相邻元素。 如果它们相同,我将 p1 的指针更改为指向 p1.next.next,否则我继续遍历列表。 但是,我在输入的解决方案中不断收到空指针异常。
Node RemoveDuplicates(Node head) {
// This is a "method-only" submission.
// You only need to complete this method.
if (head == null){
return null;
}
Node current = head;
Node runner = head;
while(current != null && runner != null && runner.next != null){
runner = runner.next;
if(runner.data == current.data){
if(current.next != null){
current = current.next.next;
}
}else{
current = current.next;
}
}
return current;
}
在我退出时,while 循环电流为空。 我认为这是问题所在。 我将如何返回更改列表的头部。
好的,虽然您已经接受了答案,但这里有一些示例代码,使用递归根据您在评论中的请求从有序列表中删除重复项。 (如果您的列表未订购,请订购 :) )
public Node removeDups(Node root) {
if (root.next == null)
return root;
root.next = removeDups(root.next);
if (root.data == root.next.data)
return root.next;
return root;
} // call as root = removeDups(root);
正如您所提到的,这里并不真正需要递归,但是您使用的是递归定义的基于节点的链表。 因此,当它有意义时,解决方案的优雅有其好处。
我喜欢它的是你没有做任何node.next.next
或需要检查那个null
情况。 一旦堆栈开始展开,您就已经可以开始检查重复项了。 那么这只是比较root.data
和root.next.data
; 您已经知道两者都存在。
您可以使用 2 个指针进行单次遍历来完成此操作。此代码也适用于单个 while 循环。
public Node deleteDuplicates(Node head) {
Node current=head;
if (head == null)
return null;
else
{
Node runner=head.next;
while(head.next!=null && runner!=null)
{
if(head.val == runner.val)
prev=runner.next;
else
{
head.next=runner;
head=head.next;
prev=runner.next;
}
}
head.next=runner;
}
return current;
}
首先,您需要在最后返回 head,以便您返回列表,而不仅仅是最后一个元素。 其次,在某些情况下,您需要修改 .next 引用而不是分配它们。
请注意,如果列表未排序,这将不起作用。
之前:1 1 3 3
之后:1 3
这段代码有效(我已经测试过了)
static Node RemoveDuplicates(Node head) {
if (head == null) return null;
Node current = head;
Node runner = head;
while (current != null && current.next != null) {
runner = current.next;
while (runner != null && runner.data == current.data) {
current.next = runner.next; // skip the repeat
runner = runner.next;
}
current = current.next;
}
return head;
}
您可以在一次遍历中完成此操作。 只需维护两个指针 temp 和 next_of_next。 对每个节点进行temp迭代,当temp和下一个节点的数据相等时,将next_of_next指向temp后的替代节点,删除temp后的节点。
Node removeDuplicates(Node head)
{
Node temp = head;
Node next_of_next;
if (head == null)
return;
while (temp.next != null)
{
if (temp.data == temp.next.data)
{
next_of_next = temp.next.next;
temp.next = null;
temp.next = next_of_next;
}
else
temp = temp.next;
}
return head ;
}
这是使用HashSet
没有递归的解决方案:
public void RemoveDuplicates()
{
if (head != null)
{
var hm = new HashSet<T>();
Node current = head;
Node prev = null;
while (current != null)
{
if (!hm.Contains(current.Value))
{
hm.Add(current.Value);
prev = current;
current = current.Next;
}
else
{
prev.Next = current.Next;
current = prev.Next;
}
}
}
return head;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.