题目描述
解题思路一
如果头结点为NULL,则直接返回head,不为NULL则进行如下操作:
-
定义一个指针 h 指向 head
-
判断 h 的指针域即其指向的下一结点是否为空,若为空则返回 head ,不为空则继续执行下面的操作
-
判断 h 的数据域与其下一结点的数据域是否相等,若相等执行4,不相等执行5
-
将 h 的下一结点的指针域赋给 h 的指针域,即改变 h 的下一结点为原先下一结点的下一结点,接着执行2
- 令 h 的下一结点为 h ,执行2
代码一
/**
* 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){
ListNode* h=head;
while(h->next){
if(h->val==h->next->val){
h->next=h->next->next;
}else{
h=h->next;
}
}
}
return head;
}
};
解题思路二(双指针)
如果头结点为NULL,则直接返回head,不为NULL则进行如下操作:
- 定义双指针,一个快指针 fast 指向头结点的下一节点,一个慢指针 slow 指向头结点
- 判断 fast 是否为空,若为空,则使 slow 的指针域为空,然后返回 head ,若不为空,则进行如下操作
- 判断 fast 的数据域和 slow 的数据域是否相等,若相等则执行4,不相等则执行5
- 不同于前一个思路的直接改变指向,而是先把 fast 往链表后移一位,可以避免多个相同数据导致的繁琐的改变指向的操作,接着执行2
- 使 slow 的指针域变为 fast ,即使 slow 的下一节点为 fast ,然后使 slow 和 fast 都向链表后移一位,接着执行2
代码
/**
* 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){
ListNode* fast=head->next;
ListNode* slow=head;
while(fast){
if(fast->val==slow->val){
fast=fast->next;
}else{
slow->next=fast;
slow=slow->next;
fast=fast->next;
}
}
slow->next=NULL;
}
return head;
}
};
很明显比解法一快一点