JZ56-删除链表中重复的结点

【题目描述】

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

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值