leecode82 83. 删除排序链表中的重复元素

83:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:

输入: 1->1->2
输出: 1->2

示例 2:

输入: 1->1->2->3->3
输出: 1->2->3

解题思路:使用前继结点,和当前结点,当俩者相等时循环判断当前结点直到不相等。

ListNode* deleteDuplicates(ListNode* head) {
		if (head == NULL || head->next == NULL)
			return head;
		ListNode* pPre = head;     //前继结点
		ListNode* pCur = head;     //当前结点
		ListNode* pDel = NULL;
		while (pCur && pCur->next)
		{
			pCur = pCur->next;
			if (pPre->val == pCur->val)
			{
				while (pCur && pPre->val == pCur->val)
				{
					pDel = pCur;
					pCur = pCur->next;
					pPre->next = pCur;
					printf("delete:%d\n", pDel->val);
					delete pDel;
					pDel = NULL;
				}
			}
			pPre = pCur;
		}

		return head;
	}

82:

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5
输出: 1->2->5

示例 2:

输入: 1->1->1->2->3
输出: 2->3

解题思路:这一题和上一题的区别就是重复了就要全部删除。相对于上一题难点就在于前继和当前结点都删除了,这个链表要怎么样接下去。最直接的思路就是再加一个前继结点不就完了,对,我就是这样想的。

根据示例1解题过程如下:

pPrepre=前前继结点 :p           pPre = 前继结点 :e             pCur = 当前结点 :c

                                 p   e   c

首先指针是这样的:1->2->3->3->4->4->5

                       p    e   c

然后前移:1->2->3->3->4->4->5

这时候满足条件要开始删除,注意这里已经不能用c结点删除了因为e结点的那个3也要删除。还要想到一点就是c后面还有重复的,所以这里循环还c再走一下:while (pCur && pPre->val == pCur->val)pCur = pCur->next;。然后从e点删直到c点。

这时候注意不能让p点向前移了,不然就p e指向一个了。

     p   e    c   

1->2->4->4->5

     p   e   c

1->2->5->null

ListNode* deleteDuplicates2(ListNode* head) {
		if (head == NULL || head->next == NULL)
			return head;
		ListNode* pPrepre = head;  //前前继结点
		ListNode retHead(0);
		retHead.next = head;
		ListNode* pPre = head;     //前继结点
		ListNode* pCur = head;     //当前结点
		ListNode* pDel = NULL;
		while (pCur && pCur->next)
		{
			pCur = pCur->next;
			if (pPre->val == pCur->val)
			{
				while (pCur && pPre->val == pCur->val)
					pCur = pCur->next;

				while (pPre != pCur)
				{
					pDel = pPre;
					pPre = pPre->next;
					printf("delete:%d\n", pDel->val);
					if (pDel == retHead.next)
					{
						retHead.next = NULL;
						pPrepre = NULL;
					}
					delete pDel;
					
					pDel = NULL;
				}

				if (pPrepre != NULL)
				{
					pPrepre->next = pPre;
				}
				else
				{
					retHead.next = pPre;
				}

			}
			if (pPre != pCur)    //2者相同说明刚刚执行了删除,前前继不用前移,不然就重合了
			{
				pPrepre = pPre;
			}
			pPre = pCur;
		}

		return retHead.next;
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值