题目简述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表1->1->2->3->3->4->4->5->5 处理后为 2->5
算法一: 非递归
时间复杂度:O(N)
思路:
先将节点全部遍历一遍,存一下每个元素的值出现的个数;
1. 如果该节点出现过,让 j 指针往后走;
2. 如果没有出现过让上一个满足的 i 指向 j ,再用 i 保存这次满足的位置,即i=j,让j在继续往后走
3.由于不确定最后满足一个位置的 i 的后面有没有自带往下指的指针,所以要将它指向NULL。
图解:
代码:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
unordered_map<int,int> hash;
ListNode* deleteDuplication(ListNode* pHead) {
if(!pHead) return NULL;
ListNode* p=pHead;
while(p){ // 记录每个值的个数
hash[p->val]++;
p=p->next;
}
ListNode* newHead=new ListNode(0);
newHead->next=pHead;
ListNode* i=newHead;
ListNode* j=pHead;
while(j){
if(hash[j->val]>1){
j=j->next; //如果该节点值个数大于1则往下走
}
else{
i->next=j; //满足个数只有一个让i指向j
i=j; //保存该节点
j=j->next; //往下遍历
}
}
i->next=NULL;
return newHead->next;
}
}; 算法二:递归
时间复杂度:O(N)
思路:
1. 找到以该节点为起点,第一个满足值不重复的节点。
2. 让该节点指向下一个满足的节点
这样就很容易通过递归实现,由于每次递归都能找到以该点为起点第一个不重复的节点,那么我们直接让第一个满足的节点a,使a->next指向从a->next开始下一个满足的节点。
代码:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL){ //若该节点为空或者只有一个节点则返回该节点
return pHead;
}
while(pHead && pHead->next && pHead->val==pHead->next->val){ //找到以该节点为其点第一个不重复的节点
while(pHead && pHead->next && pHead->val==pHead->next->val){
pHead=pHead->next;
}
pHead=pHead->next;
}
if(pHead) pHead->next=deleteDuplication(pHead->next); //使找到的那个节点指向下一个满足的节点
return pHead;
}
}; 
京公网安备 11010502036488号