题目简述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表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; } };