[Leetcode] 0083. 删除排序链表中的重复元素

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
  • 题目数据保证链表已经按升序 排列

解法

方法一:一次遍历

思路与算法

由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,因此我们只需要对链表进行一次遍历,就可以删除重复的元素。

具体地,我们从指针 \(\textit{cur}\) 指向链表的头节点,随后开始对链表进行遍历。如果当前 \(\textit{cur}\)\(\textit{cur.next}\) 对应的元素相同,那么我们就将 \(\textit{cur.next}\) 从链表中移除;否则说明链表中已经不存在其它与 \(\textit{cur}\) 对应的元素相同的节点,因此可以将 \(\textit{cur}\) 指向 \(\textit{cur.next}\)

当遍历完整个链表之后,我们返回链表的头节点即可。

细节当我们遍历到链表的最后一个节点时,\(\textit{cur.next}\)为空节点,如果不加以判断,访问 \(\textit{cur.next}\)对应的元素会产生运行错误。因此我们只需要遍历到链表的最后一个节点,而不需要遍历完整个链表。

代码

注意下面 \(\texttt{C++}\)代码中并没有释放被删除的链表节点的空间。如果在面试中遇到本题,读者需要针对这一细节与面试官进行沟通。

复杂度分析

时间复杂度:\(O(n)\),其中 \(n\) 是链表的长度。

空间复杂度:\(O(1)\)

Python3

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
        cur = head
        while cur and cur.next:
            if cur.val == cur.next.val:
                cur.next = cur.next.next
            else:
                cur = cur.next
        return head

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) {
        if(!head){
            return head;
        }
        ListNode *cur = head;
        while(cur->next){
            if(cur->val == cur->next->val){
                cur->next = cur->next->next;
            }
            else{
                cur = cur->next;
            }
        }
        return head;
    }
};
posted @ 2023-10-20 16:09  野哥李  阅读(64)  评论(0编辑  收藏  举报