「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」
题目介绍
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
示例1
输入: head = [1,1,2]
输出: [1,2]
示例2
输入: head = [1,1,2,3,3]
输出: [1,2,3]
提示:
- 链表中节点数目在范围
[0, 300]内 -100 <= Node.val <= 100- 题目数据保证链表已经按升序 排列
解题思路
此题的关键在于该链表是一个排序链表,也就是在链表中如果出现重复元素,那么重复元素将出现在该元素首次出现之后的 n 个位置。因此,我们只需要找到重复元素开始的位置,和重复元素之后第一个与重复元素不相等的元素,然后将重复元素的第一个结点的 next 指针指向重复元素之后,第一个与重复元素不相等的元素结点即可
解题步骤
- 如果该链表是一个空链表,直接返回空
null,也可以直接返回head - 定义指针
p指向链表的头节点head,定义指针q指向链表头节点的下一个结点head.next - 当
q指针没有走到链表结尾时:
- 如果
p指针所指向结点的值与q指针所指向结点的值相等,则说明q指针指向的结点为p指针指向结点的重复元素,此时p指针不动,q指针继续向前走,直到q指针指向的结点的值与p指针指向的结点的值不同 - 如果
p指针指向结点的值与q指针指向结点的值不相等,则说明q不是p的重复元素,此时直接将p结点的next指针指向q结点,然后p和q同时往前走一步
- 重复步骤 3,直到
q指针走到链表的末尾,然后将此时p结点的next指针指向null(如果p之后有重复元素,将删除p之后的所有元素) - 返回链表的头节点
head
解题代码
var deleteDuplicates = function(head) {
// 如果是空链表,直接返回null
if (!head) return null
// 定义两个指针分别指向头节点和下一个节点
let p = head, q = head.next
// 当q节点存在时
while (q) {
// 如果p的值 = q的值,q往前走一步
if (p.val === q.val) {
q = q.next
} else {
// p的值 ≠ q的值,p的下一个节点指向q
p.next = q
// p从q当前位置开始
p = q
// q从下一个节点开始
q = q.next
}
}
// 当q走到链表尾部时,直接删除p之后的节点
p.next = null
return head
};