题目描述
存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。
返回同样按升序排列的结果链表。
题解
没做过【Leetcode】83. 删除排序链表中的重复元素 的建议先做83题,那边是用了双指针法,把重复元素删除。
本题是直接把出现重复元素的节点,一个不剩的删除。需要用到三指针。
一个dumyhead放在head的前面,pre指向dummyhead,mid指向head,cur指向head.next。三个指针,老样子,如果mid和cur这前面这两兄弟如果没有发现重复元素,则三指针右移。
如果发现重复,怎么删除呢?记录下出现重复元素的值,即为val,让cur指针一直移动到值不为val的地方,mid跟在cur的前一个位置,pre不动(如果cur一直移动到了null,那就更好了,直接让pre指向null,就删除完毕)。
之后就是正常的删除操作,让mid指向null,再回到cur,这样重复序列的右边就断连了,让pre.next指向cur,重复序列的左边就断连了,然后让cur再右移一位,摆好前中后三指针的位置。
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.1 MB, 在所有 Java 提交中击败了5.73%的用户
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode pre = dummyHead;
ListNode mid = head;
ListNode cur = head.next;
while (mid != null && cur != null) {
if (mid.val != cur.val) {
pre = pre.next;
mid = mid.next;
cur = cur.next;
}
else {
int val = cur.val;
while (cur != null && cur.val == val) {
mid = mid.next;
cur = cur.next;
}
if (cur == null) {
pre.next = null;
}
else { // cur != null
mid.next = null;
mid = cur;
cur = cur.next;
pre.next = mid;
}
}
}
return dummyHead.next;
}
}