问题:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
输入:链表头节点指针
思路:
由于链表是有序的,只需要通过比较邻近两个节点是否相等,就可以找到所有重复的元素,然后利用指针操作将重复的节点删除。
代码:
/**
* 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* node=head;
while(node!=nullptr&&node->next!=nullptr)
{
if(node->val==node->next->val)
{
node->next=node->next->next; // 为了不断开连接,删除node->next。
}
else
{
node=node->next;
}
}
return head;
}
};
复杂度分析:时间复杂度O(n),空间复杂度为O(1).
扩展:
问题:给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。(leetcode 82 medium)
思路:
递归法
代码:
/**
* 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==nullptr)
return nullptr;
if(head->next==nullptr)
return head;
int value=head->val;
ListNode* node=head->next;
if(node->val==value)
{
while(node&&node->val==value)
{
node=node->next;
}
return deleteDuplicates(node);
}
else
{
head->next= deleteDuplicates(node);
return head;
}
}
};
// nowcoder
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
//if(pHead==nullptr||pHead->next==nullptr)
// return nullptr;
if(pHead==nullptr)
return nullptr;
if(pHead->next==nullptr)
return pHead;
ListNode* pNode=pHead;
if(pNode->next!=nullptr) //递归外层循环不用while循环
{
if(pNode->val==pNode->next->val)
{
ListNode* temp=pNode->next;
while(temp!=nullptr&&pNode->val==temp->val)
temp=temp->next;
return deleteDuplication(temp);
}
else
{
pNode->next=deleteDuplication(pNode->next);
}
}
return pNode;
}
};
此外,还有一种算法容易理解,利用二级指针**runner,如果为需要被删除节点,则将runner节点更换为一个不等于runner节点值的最邻近的节点,如果为不需被删除的节点,则将runner地址更换为下一个节点的指针。代码如下:
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
ListNode **runner = &head;
if(!head || !head->next)return head;
while(*runner)
{
if((*runner)->next && (*runner)->next->val == (*runner)->val)
{
ListNode *temp = *runner;
while(temp && (*runner)->val == temp->val)
temp = temp->next;
*runner = temp;
}
else
runner = &((*runner)->next);
}
return head;
}
};
复杂度分析:时间复杂度O(n),空间复杂度为O(n)。