原题
链表简单1 种解法

#83删除排序链表中的重复元素

压缩有序链表中的连续重复值,使每个值只保留一个节点。

#链表

原题

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

示例 1:

输入:head = [1,1,2]
输出:[1,2]

示例 2:

输入:head = [1,1,2,3,3]
输出:[1,2,3]

提示:

  • 链表中节点数目在范围 [0, 300]
  • -100 <= Node.val <= 100
  • 题目数据保证链表已经按升序 排列

查看原题

解题主线

  1. 重复值在有序链表中必然相邻,比较当前节点与 next 即可。
  2. 遇到重复节点时绕过 next;遇到新值时才推进当前指针。

解法 1:相邻节点去重

利用链表有序的条件,一次遍历删除与当前节点同值的直接后继。

  • 时间复杂度: O(n)

  • 空间复杂度: O(1)

JAVA
public class Solution {
    static final class ListNode {
        int val;
        ListNode next;
        ListNode(int val) { this.val = val; }
    }

    public ListNode deleteDuplicates(ListNode head) {
        ListNode current = head;
        // 有序性保证同值节点连续出现,只需比较相邻节点
        while (current != null && current.next != null) {
            if (current.val == current.next.val) {
                // 绕过重复节点后不移动 current,以继续清理同一组重复值
                current.next = current.next.next;
            } else {
                // 仅遇到新值时推进,保持 current 指向当前已保留值
                current = current.next;
            }
        }
        return head;
    }
}

实现提示

  • 这是对旧 HashSet 实现的等价优化:时间仍为 O(n),额外空间降为 O(1)。

边界与易错点

  • 旧文件用 HashSet 判断重复,结果正确但忽略了有序性并额外消耗 O(n) 空间。
  • 本题每个值保留一个节点,与第 82 题删除整组重复值不同。

整理来源

由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。

  • Q082_linkedList_delDuplicates.java