题目
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入: head = [1,2,3,3,4,4,5]
输出: [1,2,5]
示例 2:
输入: head = [1,1,1,2,3]
输出: [2,3]
提示:
- 链表中节点数目在范围
[0, 300]内 -100 <= Node.val <= 100- 题目数据保证链表已经按升序 排列
题解
由于题目中给定的链表时排好序的,因此重复的元素在链表中的位置都是相邻连续的,只需要对链表进行一次遍历,就可以删除重复的元素,注意链表的头结点可能被删除,因此需要一个额外的哑结点(dummy) 指向链表的头结点
具体流程如下:
- 初始化时,
dummy指针指向链表的头结点,声明cur = dummy指向链表的哑结点。 - 对链表遍历,如果
cur.next.val === cur.next.next.val, 说明元素重复,就需要将cur.next自己和它之和的拥有相同元素的值的节点全部删除,先用x记录cur.next.val, 随后不断地将cur.next从链表中移除,直到cur.next为空节点或者其元素值不等于x, 此时,链表中所有为元素x的节点全部删除。 - 如果当前
cur.next.val !== cur.next.next.val, 即元素不相同, 那说明链表中只有一个元素值为cur.next的节点,直接将cur指向cur.next - 遍历完整个链表后,返回链表的哑结点的下一个节点
dummy.next即可
代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var deleteDuplicates = function(head) {
if (head == null) return head;
// 由于链表中头结点可能被删除,所以需要额外使用一个哑结点,指向头结点
const dummy = new ListNode(-1, head);
let cur = dummy;
// 一开始cur.next指向head, cur.next.next 指向 head.next;
while(cur.next && cur.next.next) {
// 说明下一个节点和下下个节点重复,需要全部删除
if (cur.next.val === cur.next.next.val) {
const x = cur.next.val;
// 继续遍历,看下下下节点是否和下下节点重复,重复就删除
while(cur.next && cur.next.val === x) {
cur.next = cur.next.next;
}
} else {
cur = cur.next;
}
}
return dummy.next;
};