【题目描述】
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
【尝试解法】
图1.借鉴==JZ55的哈希法==
//1.先创建虚拟头节点
//2.将结点加入到set中,发现相同的将不进行cur的赋值
图2.改正为val,而不是地址,思路对了,但是循环写错了。pHead=pHead->next,应该写在if外,不然pHead会死在while中
图3.改正之后,运行结果如此,但是看错了题意,唉。
//题意要求只要是重复的都删去,一个都不留下
图4.终于结果正确!!!
解法1.哈希法
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
unordered_map<int, int> mp;
ListNode *p = pHead;
ListNode *pp = pHead;
auto dummy = new ListNode(-1);//建立虚拟头结点
auto cur = dummy;
while (p) {
++mp[p->val];
p = p->next;
}
while (pp) {
if (mp[pp->val] == 1 ) {
cur->next = pp;
cur = cur->next;
}
pp = pp->next;
}
cur->next = nullptr;
//此句是为了防止最后一个值也是重复的,例如:11233455,如果没有此句输出为2455,因为cur指针没断
return dummy->next;
}
};
【官方解法】
解法2.使用set,暴力解法
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (!pHead) return pHead;
//1.数据处理,将重复的值找出来
set<int> st;
ListNode *pre = pHead;
ListNode *cur = pHead->next;
while (cur) {
if (pre->val == cur->val) {
st.insert(pre->val);//把相等的值存在st中
}
pre = pre->next;
cur = cur->next;
}
//2.构建新链表,得到答案
ListNode *vhead = new ListNode(-1);
vhead->next = pHead;
pre = vhead;
cur = pHead;
while (cur) {
if (st.count(cur->val)) {//st.count 在st中寻找数值是否存在
cur = cur->next;
pre->next = cur;
}
else {
pre = pre->next;
cur = cur->next;
}
}
return vhead->next;
}
};
解法3.直接删除法(类似于双指针)
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
ListNode *vhead = new ListNode(-1);
vhead->next = pHead;
ListNode *pre = vhead, *cur = pHead;
while (cur) {
if (cur->next && cur->val == cur->next->val) {
cur = cur->next;
while (cur->next && cur->val == cur->next->val) {
cur = cur->next;
}
cur = cur->next;
pre->next = cur;
}
else {
pre = cur;
cur = cur->next;
}
}
return vhead->next;
}
};