这题难的地方是要把重复元素全部都删除,所以肯定要用虚拟头节点,因为头节点会变。再遍历的时候,要从p->next开始,所以这里的写法是这样的。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* p = dummy;
while(p&&p->next){
ListNode* q = p->next;
while(q&&q->val==p->next->val) q = q->next;
//
//
}
return dummy->next;
}
};
这样有个问题,就是当不是相同节点时,就会跳过一个节点,如果是这种情况p = p->next,p往后走一步,否则p走到q的位置。因此代码如下:
/**
* 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* dummy = new ListNode(-1);
dummy->next = head;
auto p = dummy;
while(p&&p->next){
auto q = p->next;
while(q && p->next->val == q->val) q = q->next;
if(p->next->next == q){
p = p->next;
}else{
p->next = q;
}
}
return dummy -> next;
}
};
递归做法:
定义ListNode* deleteDuplicates(ListNode* head)表示删除以head开头的含有重复元素的节点,如果节点为空,直接返回,如果节点有重复,处理到没有重复,处理后面,如果没有重复,那么处理后面,头节点还是当前头节点。
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(head == nullptr){
return nullptr;
}
if(head->next && head->val == head->next->val){
while(head->next && head->val == head->next->val){
head = head->next;
}
return deleteDuplicates(head->next);
}else{
head->next = deleteDuplicates(head->next);
return head;
}
}
};