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
- 题目数据保证链表已经按升序 排列
思路:
法一:一次遍历
由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,因此我们只需要对链表进行一次遍历,就可以删除重复的元素。
- 我们从指针
tem
指向链表的头节点,随后开始对链表进行遍历。 - 如果当前
tem
与tem.next
对应的元素相同,那么我们就将tem.next
从链表中移除; - 否则说明链表中已经不存在其它与
tem
对应的元素相同的节点,因此可以将temr
指向tem.next
。
注意下面 C++代码中并没有释放被删除的链表节点的空间。如果在面试中遇到本题,读者需要针对这一细节与面试官进行沟通。
法二:递归
链表具有天然的递归性,链表看成其头节点后挂接一个更短的链表,这个更短的链表看成其头节点后面挂接一个更更短的链表,依次类推。因此本题可以按照如下步骤处理:
- 删除更短链表中所有重复的元素;
- 判断原链表的头节点的值是否等于经过第 1 步处理后的更短链表头节点的值;
- 若相等,则返回更短的链表;
- 否则,将更短的链表挂接在原链表的头节点的后面,再返回。
代码:(Java、C++)
法一:一次遍历
Java
/*** 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) {ListNode tem = head;while(tem != null && tem.next != null){if(tem.next.val == tem.val) {tem.next = tem.next.next;}else{tem = tem.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) {ListNode* tem = head;while(tem != NULL && tem->next != NULL){if(tem->next->val == tem->val) {tem->next = tem->next->next;}else{tem = tem->next;}}return head;}
};
法二:递归
Java
/*** 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;}head.next = deleteDuplicates(head.next);return head.val == head.next.val ? head.next : 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 == NULL || head->next == NULL){return head;}head->next = deleteDuplicates(head->next);return head->val == head->next->val ? head->next : head;}
};
运行结果:
复杂度分析:
- 时间复杂度:O(n)O(n)O(n),其中
n
是链表的长度 - 空间复杂度:O(1)O(1)O(1)
题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我 leetCode专栏,每日更新!