给定一个已排序的链表 head
,请删除链表中所有重复的元素,使得每个元素只出现一次,并返回链表的头节点。
输入格式
一个已排序的链表的头节点 head
。链表节点的值为整数。
输出格式
返回删除重复元素后的链表头节点。链表节点的值为整数。
核心思路
由于链表已排序,重复元素必然连续出现。只需遍历链表,逐个比较相邻节点,若值相同则删除后者,确保每个值仅保留一次。
算法步骤
- 边界处理:链表为空或仅有一个节点时直接返回。
- 遍历链表:使用
current
指针扫描链表。 - 去重逻辑:
- 若当前节点值与下一节点值相同 → 删除下一节点。
- 否则 → 移动指针至下一节点。
C++ 代码实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* current = head;
while (current != nullptr && current->next != nullptr) {
if (current->val == current->next->val) {
current->next = current->next->next; // 删除重复节点
} else {
current = current->next; // 移动指针
}
}
return head;
}
};
复杂度分析
- 时间复杂度:O(n),每个节点仅被访问一次。
- 空间复杂度:O(1),仅使用常量额外空间。
关键点解析
- 双指针简化操作:通过单指针
current
直接操作链表,无需额外数据结构。 - 原地修改:直接在原链表上删除节点,避免创建新链表。
- 有序性利用:依赖链表已排序的特性,确保重复元素连续出现,简化比较逻辑。