1. 问题描述
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
2. 解题思路
① 如果链表为空或者仅有一个节点则直接返回 head。
② 设置哑节点,设置 prev 指针,初始化指向哑节点;同时设置 curr 指针,初始化指向链表的头节点。curr 指针表示当前指向的节点,若当前节点不为空且下一节点也不为空则持续进行循环,考虑两种情况:
(1)如果下一节点的值与当前节点的值一样,则当前指针即 curr 指针一直走,直到遇见不相等值的节点。此时,将前置指针 prev 的 next 指向 curr 指针的 next,同时将 curr 指针后移一位。
(2)如果 下一节点的值与当前节点的值不一样,则将 prev 指针指向 curr 指针,同时 curr 指针后移一位。
③ 最终只需返回 哑节点的 next 即可。
3. 代码实现
/**
* 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 dummy = new ListNode(-1);
dummy.next = head;
// 记录前置节点,处理要删除的情况(初始化指向哑节点)
ListNode prev = dummy;
// 记录当前节点, 用于遍历整个链表(初始化指向链表的头节点)
ListNode curr = head;
while (curr != null && curr.next != null) {
// 下一个节点值与当前节点值相等
if (curr.val == curr.next.val) {
// 当前指针一直走,直到遇见不相等值的节点
while (curr.next != null && curr.val == curr.next.val) {
curr = curr.next;
}
prev.next = curr.next;
curr = curr.next;
} else {
prev = curr;
curr = curr.next;
}
}
return dummy.next;
}
}