法1:非递归,遍历的同时删除。添加一个辅助头节点,方便索引整个链表;设置pre、last指针,pre指向当前确定不重复的那个结点,last为工作指针,一直往后面搜索。
需要注意的问题:当头结点重复的时候,要删除头结点。(通过新建头结点解决)
时间复杂度:O(n)
空间复杂度:O(1)
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ public class Solution { public ListNode deleteDuplication(ListNode pHead) { if(pHead==null||pHead.next==null)// 只有0个或1个结点,则返回
return pHead; ListNode Head=new ListNode(0); Head.next=pHead; ListNode pre=Head,last=Head.next; while(last!=null){ if(last.next!=null&&last.val==last.next.val){
// 当前结点(last指向的结点)是重复结点
while(last.next!=null&&last.val==last.next.val){// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点
last=last.next; } pre.next=last.next; last=last.next; }else{// 当前结点不是重复结点
last=last.next; pre=pre.next; } } return Head.next; } }
法2:递归。
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ public class Solution { public ListNode deleteDuplication(ListNode pHead) { if(pHead==null||pHead.next==null) return pHead; if(pHead.val==pHead.next.val){ // 当前结点pHead是重复结点 ListNode tmp=pHead.next; while(tmp!=null&&tmp.val==pHead.val){// 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点 tmp=tmp.next; } return deleteDuplication(tmp);// 从第一个与当前结点不同的结点开始递归 }else{ pHead.next=deleteDuplication(pHead.next);// 保留当前结点,从下一个结点开始递归 return pHead; } } }