给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
示例 2:
输入: 1->1->2->3->3
输出: 1->2->3
因为链表已经排好序,若固定一个节点,遍历它之后的节点,与他重复的数应该全在它后面的节点,只需将这些节点删除即可。我的方法的时间复杂度应该是O(N2)。
/**
* 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 *p=head;
while(p)
{
int val=p->val;
ListNode *per=p,*cur=per->next;
while(cur)
{
if(cur->val==val)
{
per->next=cur->next;
}
else
{
per=per->next;
}
cur=cur->next;
}
p=p->next;
}
return head;
}
};
今天看了看题解,发现我的思路可以用时间复杂度O(N)的方法来实现
/**
* 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 *cur=head;
while(cur!=NULL &&cur->next!=NULL)
{
if(cur->val==cur->next->val)
{
cur->next=cur->next->next;
}
else
{
cur=cur->next;
}
}
return head;
}
};
其实我前面的写过的删除链表节点的题目就已经用到双指针中的快慢指针了,我发现这个题也可以用快慢指针来解决
/**
* 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) {
if(head==NULL || head->next==NULL)
{
return head;
}
ListNode* slow = head;//声明一个指向头节点的慢指针
ListNode* fast = head->next;//声明一个指向头节点下一个的节点的快指针
while(slow->next!=NULL)//快指针比慢指针移动快一位,所以循环条件为快指针不为空指针
{
if(slow->val==fast->val)//快慢指针指向节点的值相同,即出现重复节点
{
if(fast->next==NULL)//快指针指向节点下一个节点为空,说明快指针指向链表的尾节点
{
slow->next=NULL;//删除后慢指针为尾节点
}
else//快指针不指向链表的尾节点
{
slow->next=fast->next;
fast=fast->next;
}
}
else//没有重复节点,快慢指针分别指向她们的下一个节点
{
fast=fast->next;
slow=slow->next;
}
}
return head;
}
};
这篇文章记录了我刷题的过程,不能说是迭代的过程,因为其实快慢指针并没有O(N)的直接法来得快,但是也提供了一种新的思路和视角。