Remove Duplicates from Sorted List II-- Leetcode 我的java题解

来源:互联网 发布:答题赚钱的软件 编辑:程序博客网 时间:2024/09/21 09:04

题目描述:Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.


这题对我来说挺难的,我弄了一晚上。总是理不顺。修修补补的。哎呀,上学学的都浮于表面。遇到题目就不会了。纠结了好久,上来就重复的话,得删掉头指针,怎么删。这个想了好久。

我测试了{1,1,1,2,2,3,4} 这类长的链表,都没有问题。一旦输入 {1,2}, {1} ,{1,1},{1,2,3},{1,2,2} 这几种极端的链表。我几乎每次都报Submission Result: Wrong Answer. 修改了好久。做这种题目,极端情况一定得考虑清楚。要想的周全,经得起考验。

========

我发现,同样的代码,在intellij里不报编译的错误,而在leetcode里却报错java.lang.NullPointerException,大概是leetcode更严格吧。

我的被leetcode接受的代码,写的很复杂。完全是自己磨啊磨出来的。有时间我一定要到网上看看其他人的写法。
我的想法就是:
增加一个头结点headnew,然后指向原有的链表。这样防止一上来就是{1,1,1,2}这样的,丢失头结点。这个结点不动,一直放在那,用于输出。
增加一个标志deleteflag,记录相同的数列里的第一个数要不要删掉。
增加一个游标index,移动着删除相同数据的结点。
代码如下,我测试过没问题。如果你觉得有问题,请告诉我一下。
/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */public class Solution {    public ListNode deleteDuplicates(ListNode head) {        ListNode index=new ListNode(0);        ListNode headnew=new ListNode(0);        index.next=head;        headnew=index;        boolean deleteflag=false;        if(head==null) return null;        if(head.next==null) return head;         while(index!=null){             if(index.next.next==null&&deleteflag==false) return headnew.next;             if(index.next.next==null&&deleteflag==true){                index.next=null;                 return headnew.next;             }            if(index.next.val==index.next.next.val){                deleteflag=true;//记得要删除相同序列的第一个数                index.next.next=index.next.next.next;            }            else{                if(deleteflag==true){                    index.next=index.next.next;                }                else                {                  index=index.next;                }                deleteflag=false; //当找到不相同的数时,这个标志就要复原成false            }        }        return headnew.next;    }}
测试代码

public static void main(String[] args) {    removeduplicatelist r = new removeduplicatelist();    ListNode L = new ListNode(1);    L.next = new ListNode(2);    L.next.next = new ListNode(2); /*   L.next.next.next = new ListNode(2);    L.next.next.next.next = new ListNode(2);    L.next.next.next.next.next = new ListNode(4);    L.next.next.next.next.next.next = new ListNode(5);    L.next.next.next.next.next.next.next = new ListNode(6);    */    //print original string    ListNode temp = new ListNode(0);    temp = L;    while (temp != null) {        System.out.print(temp.val + " ");        temp = temp.next;    }    System.out.println("\n");    L = r.deleteDuplicate2(L);    while (L != null) {        System.out.print(L.val + " ");        L = L.next;    }}

这个特别搞脑子,我脑子转的慢极了。所以写的非常复杂。如果您有更好的代码。恳请留言告诉我。我很乐意学习。


在网上找到牛人的代码一款:

public class Solution {    public ListNode deleteDuplicates(ListNode head) {        if(head == null || head.next == null)            return head;                ListNode dummy = new ListNode(0);        dummy.next = head;        head = dummy;        while (head.next != null && head.next.next != null) {            if (head.next.val == head.next.next.val) {                int val = head.next.val;                while (head.next != null && head.next.val == val) {                    head.next = head.next.next;                }                        } else {                head = head.next;            }        }                return dummy.next;    }}

另一款牛人的代码:

只是这里要把出现重复的元素全部删除。其实道理还是一样,只是现在要把前驱指针指向上一个不重复的元素中,如果找到不重复元素,则把前驱指针知道该元素,否则删除此元素。算法只需要一遍扫描,时间复杂度是O(n),空间只需要几个辅助指针,是O(1)。代码如下: 

  1. public ListNode deleteDuplicates(ListNode head) {  
  2.     if(head == null)  
  3.         return head;  
  4.     ListNode helper = new ListNode(0);  
  5.     helper.next = head;  
  6.     ListNode pre = helper;  
  7.     ListNode cur = head;  
  8.     while(cur!=null)  
  9.     {  
  10.         while(cur.next!=null && pre.next.val==cur.next.val)  
  11.         {  
  12.             cur = cur.next;  
  13.         }  
  14.         if(pre.next==cur)  
  15.         {  
  16.             pre = pre.next;  
  17.         }  
  18.         else  
  19.         {  
  20.             pre.next = cur.next;  
  21.         }  
  22.         cur = cur.next;  
  23.     }  
  24.       
  25.     return helper.next;  
  26. }  

可以看到,上述代码中我们创建了一个辅助的头指针,是为了修改链表头的方便。前面介绍过,一般会改到链表头的题目就会需要一个辅助指针,是比较常见的技巧。

只是我怎么没想到利用前驱指针。。。。。。。呜呜呜呜


0 0
原创粉丝点击