文章目录
- 删除单链表中的重复节点
- 题目描述
- 解题思路
- 代码实现
删除单链表中的重复节点
力扣链接
题目描述
编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。
示例1: 输入:[1, 2, 3, 3, 2, 1] 输出:[1, 2, 3] 示例2: 输入:[1, 1, 1, 1, 2] 输出:[1, 2]
提示:
- 链表长度在[0, 20000]范围内。
- 链表元素在[0, 20000]范围内。
解题思路
思路一:
- 定义两个指针current和p来逐个遍历链表
- current指向的元素依次与p指向的元素的下一个元素进行比较
- 若相同则删去p的下一个元素【即使p的next指向下下个元素(p的next的next),继续循环比较】
- 若不相同则p往后移动一个位置,继续循环比较,直到p所指元素的下一个为空【只要后一个不为空则继续比较,否则 停止本次比较】
- 若所有元素都与后面元素比较过了,则返回当前链表
head
- current指向的元素依次与p指向的元素的下一个元素进行比较
思路二:
- 定义p指针遍历链表,利用set,遇到一个元素就去set中找是否包含这个元素
- 如果set中包含了当前元素,就说明当前遍历的元素属于重复节点,则删除
- 利用
s.count
查询函数,返回的是一个整数,表示查询到元素的个数
- 利用
- 如果不包含,则添加进set中,并将p指针后移
- 如果set中包含了当前元素,就说明当前遍历的元素属于重复节点,则删除
思路三:利用标记数组,标记当前值是否出现过
代码实现
//提供完整的代码,可以在C编辑器中进行测试
#include <iostream>
#include <set>
using namespace std;
struct ListNode{
int val;
ListNode *next;
ListNode(int x) : val(x),next(NULL){}
};
class Solution{
public:
//方法一:
ListNode* removeDuplicateNodes(ListNode* head){
//判断是否需要遍历
if(head==NULL||head->next==NULL) return head;
ListNode* current = head;
while(current){//第一重循环:将第i个元素依次与后面元素进行比较(i从1到最后)
ListNode *p = current;
while(p->next){//第二重循环:与后1个比、后2个比、后三个比...与最后一个比
if(p->next->val == current->val){
p->next = p->next->next;//删除p后面这个重复的元素
}else{
p = p->next;//p后移
}
}
current = current->next;//将第i+1个元素开始依次与后面元素进行比较
}
return head;//这里返回的一定是head,此时的head后面的链表已经删除了重复的元素
}
//方法二:
ListNode* removeDuplicateNodes2(ListNode* head){
if(head==NULL||head->next==NULL) return head;
set<int> s;
ListNode* p = head;
s.insert(p->val);
while(p->next){//只要还没到最后一个元素,就遍历
if(s.count(p->next->val)!=0){//包含了,则重复
p->next = p->next->next;
}else{ //不重复,添加进去、后移
s.insert(p->next->val); //或者可以先后移再添加,p=p->next;s.insert(p->val);
p = p->next;
}
}
return head;
}
//方法三:
ListNode* removeDuplicateNodes3(ListNode* head){
if(head==NULL||head->next==NULL) return head;
//利用val的值在0~20000之间,标记是否出现过
int index[20001] = {0};
index[head->val] = 1;
struct ListNode* q = head;
while(q->next){
//下一个val未出现过,保存下一个val
if(index[q->next->val]==0){
index[q->next->val] = 1;
q = q->next;
}else{ //下一个val出现过,删除下一个节点
q->next = q->next->next;
}
}
return head;
}
//链表打印函数
void ListPrintf(ListNode* head){
ListNode* pos = head;
while(pos){
cout<<pos->val<<"->";
pos = pos->next;
}
cout <<"NULL"<<endl;
}
//尾部插入函数
void ListBackInsert(ListNode** pphead,int val){
ListNode* newNode = new ListNode(val);
if(*pphead==NULL){
*pphead = newNode;
}else{
ListNode* pos = *pphead;
while(pos->next!=NULL){
pos = pos->next;
}
pos->next = newNode;
}
}
};
int main(){
ListNode* test = new ListNode(1);
ListNode* result;
class Solution s;
s.ListBackInsert(&test,2);
s.ListBackInsert(&test,3);
s.ListBackInsert(&test,3);
s.ListBackInsert(&test,2);
s.ListBackInsert(&test,1);
s.ListPrintf(test);
result = s.removeDuplicateNodes(test);
//result = s.removeDuplicateNodes2(test);
//result = s.removeDuplicateNodes3(test);
s.ListPrintf(result);
return 0;
}
结果: