Leetcode: Remove Duplicates from Sorted List II
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.
难度:70,参考,现在要把前驱指针指向上一个不重复的元素中,如果找到不重复元素,则把前驱指针知道该元素,否则删除此元素。算法只需要一遍扫描,时间复杂度是O(n),空间只需要几个辅助指针,是O(1)
程序中prev指的元素定义为是上一个不重复的元素,最开始指向dummy node, cur指向定义为下一个元素为我们需要的不重复元素,最开始指向head。最后删除重复元素就是删除(prev,cur]区间内的元素,只需要prev.next = cur.next。而判断前后两个元素是否是重复只需要每次比较prev.next与cur.next, 如果重复,那么就把cur=cur.next一直往后移直到prev.next != cur.next或者到最末。如果发生了重复删除,prev不动,cur往后移动一位,否则没有重复prev和cur都要往后移一位,判断是否发生了删除就是看prev.next是否就是cur(prev.next == cur? 注意这里是内存地址一致,不是仅仅值相等)
比较好的做法:之所以18行是while(cur!=null)而不是 while(cur.next !=null) Is because in the while loop line 19 - 20 cur can also move forward, may move to the last node and jump out of the inner while loop, then at line 28, cur further move forward from the last node to null, so this time cur == null . So if the outer loop condition is cur.next !=null, errors will occur.
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { 7 * val = x; 8 * next = null; 9 * } 10 * } 11 */ 12 public class Solution { 13 public ListNode deleteDuplicates(ListNode head) { 14 ListNode dummy = new ListNode(-1); 15 dummy.next = head; 16 ListNode cur = head; 17 ListNode prev = dummy; 18 while (cur != null) { 19 while (cur.next != null && prev.next.val == cur.next.val) { //compare prev.next and cur.next to see if duplicates 20 cur = cur.next; //if duplicates, cur keeps moving one step furthur until cur.next != prev.next, (prev, cur] should be deleted 21 } 22 if (prev.next == cur) { //to see if there has been duplicate or not 23 prev = prev.next; //no duplicates, prev and cur should move 1 step furthur together 24 } 25 else { 26 prev.next = cur.next; //duplicates exists, delete the duplicates, only moves cur 1 step further, prev stays. 27 } 28 cur = cur.next; 29 } 30 return dummy.next; 31 } 32 }
另一种做法:第14行必须要在runner.next!=null的情况下才敢runner= runner.next, 否则runner就会指向null,下一次while循环判断runner.next!=null就会出错
1 public class Solution { 2 public ListNode deleteDuplicates(ListNode head) { 3 if (head == null) return null; 4 ListNode dummy = new ListNode(-1); 5 dummy.next = head; 6 ListNode walker = dummy; 7 ListNode runner = head; 8 while (runner.next != null) { 9 if (walker.next.val == runner.next.val) { 10 while (runner.next!=null && walker.next.val == runner.next.val) { 11 runner = runner.next; 12 } 13 walker.next = runner.next; 14 if (runner.next != null) runner = runner.next; 15 } 16 else { 17 walker = walker.next; 18 runner = runner.next; 19 } 20 } 21 return dummy.next; 22 } 23 }