从链接列表中删除重复项

时间:2018-05-12 16:58:38

标签: java

所以我有一个链表,我试图从中删除重复项。

我想到的基本算法就是使用跑步技术。我保留两个指针来比较相邻元素。如果它们是相同的,我将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循环时,current is null。我认为这是问题所在。我如何返回更改列表的头部。

5 个答案:

答案 0 :(得分:1)

您可以使用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; 
    }

答案 1 :(得分:0)

首先,你需要在最后返回头部,这样你才能返回列表,而不仅仅是最后一个元素。 其次,你需要修改.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;
}

答案 2 :(得分:0)

您可以在一次遍历中执行此操作。只保持两个指针临时 和next_of_next。对每个节点进行temp迭代,当temp和下一个节点的数据相等时,在temp之后将next_of_next指向备用节点,并在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 ;
}

答案 3 :(得分:0)

好的,虽然您已经接受了答案,但这里有一些示例代码使用递归来根据您的请求在评论中删除有序列表中的重复项。 (如果您的清单没有订购,请订购:))

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.dataroot.next.data;你们都知道这两者都存在。

答案 4 :(得分:0)

这里有一个使用 public void ConfigureServices(IServiceCollection services) { services.AddHttpClient(); //.................. } 没有递归的解决方案:

HashSet