题目链接
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

解题思路
方法一:使用set,暴力解法
根据题意,显然如果能够知道重复的值是什么,然后再遍历一次单链表,删除重复值即可。
找重复值的具体步骤:
1.初始化:set
2. 遍历单链表相邻两个元素,如果相等,就加入到set当中
3. 直到单链表遍历完
删除重复值的具体步骤:
1.初始化:pre指针指向重复值的前一个节点,cur指向当前遍历的节点值
2.遍历单链表当前元素,然后再set中检查,如果是重复值,就删除,pre->next = cur->next
3. 否则,不是重复值,pre = pre->next, cur = cur->next
4. 知道单链表遍历完
class Solution {public:ListNode* deleteDuplication(ListNode* pHead){if (!pHead) return pHead;set<int> st;ListNode *pre = pHead;ListNode *cur = pHead->next;while (cur) {if (pre->val == cur->val) {st.insert(pre->val);}pre = pre->next;cur = cur->next;}ListNode *vhead = new ListNode(-1);vhead->next = pHead;pre = vhead;cur = pHead;while (cur) {if (st.count(cur->val)) {cur = cur->next;pre->next = cur;}else {pre = pre->next;cur = cur->next;}}return vhead->next;}};
- 时间复杂度:O(2n),遍历了2次单链表
- 空间复杂度:最坏O(n), 最好O(1)
方法二:直接删除法
根据方法一,可以优化,在遍历单链表的时候,检查当前节点与下一点是否为相同值,如果相同,继续查找祥同值的最大长度,然后指针改变指向。
/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public:ListNode* deleteDuplication(ListNode* pHead){if(!pHead||!pHead->next)return pHead;ListNode *vhead = new ListNode(-1);vhead->next = pHead;ListNode *pre = vhead,*cur = pHead;while(cur){if(cur->next&&(cur->val==cur->next->val)){int tmp = cur->val;while(cur&&cur->val==tmp){cur = cur->next;}pre->next = cur;}else{pre = cur;cur = cur->next;}}return vhead->next;}};/*struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}};*/class Solution {public:ListNode* deleteDuplication(ListNode* pHead) {ListNode* hair = new ListNode(0);hair->next = pHead;ListNode* pre = hair;ListNode* cur = pHead;while(cur){if(cur->next&&cur->val==cur->next->val){cur = del(cur);pre->next = cur;}else{pre = cur;cur = cur->next;}}return hair->next;}ListNode* del(ListNode* node){int val = node->val;while(node&&node->val==val){node = node->next;}return node;}};
/*** 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 hair = new ListNode();hair.next = head;ListNode pre = hair, cur = head;while(cur!=null){int val = cur.val;boolean flag = true;while(cur.next != null && cur.next.val == val){cur = cur.next;flag = false;}if(flag){pre = pre.next;}else{pre.next = cur.next;}cur = cur.next;}return hair.next;}}
保留重复节点中第一个节点
/**
* 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 hair = new ListNode();
hair.next = head;
ListNode pre = head;
ListNode cur = head;
while(cur!=null){
int val = cur.val;
while(cur!=null && cur.val == val){
cur = cur.next;
}
pre.next = cur;
pre = cur;
}
return hair.next;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
