剑指offer:删去链表中重复的节点。(题解源代码加图解)

题目

剑指offer,删除链表中的重复节点。
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。

示例1,链表1->2->3->3->4->4->5
处理后为 1->2->5

示例2
输入
{ 1, 2, 3, 3, 4, 4 }
返回值
{ 1, 2 }

解析

因为是删重,所以不保留重复节点。
用两个指针cur 和next判断是否重复,
1、如果不重复保留下来,此时需要上一个节点,用prev保留,为了方便第一个节点的链接,我们创建一个哨兵位的头节点pphead。
2、重复了则不保留,释放cur后,cur和next继续向后走,直到他俩不同。
3、那么cur和next走到NULL时又有两种情况
情况1:最后一个数字保留,如示例1,最简单,直接保留即可。
情况2:最后一个数字不保留,如示例2,此时需要释放它,再将prev的下一个置NULL;

图解

在这里插入图片描述

代码

#include<Windows.h>
#include<stdio.h>
#include <assert.h>
#pragma warning (disable:4996)
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
	ListNode* deleteDuplication(ListNode* pHead)
	{
		if (pHead == NULL || pHead->next == NULL)
		{
			return pHead;
		}
		ListNode*pphead = (ListNode*)malloc(sizeof(ListNode));
		ListNode*prev = pphead;
		pphead->next = pHead;
		ListNode*cur = pHead;
		ListNode*next = pHead->next;
		while (next)
		{
			if (cur->val != next->val)
			{
				prev->next = cur;
				prev = prev->next;
				cur = cur->next;
				next = next->next;
			}
			else
			{
				while (next->val == cur->val)
				{
					ListNode*temp = cur;
					cur = next;
					next = next->next;
					free(temp);
					if (next == NULL)
					{
						break;
					}
				}
				free(cur);
				cur = next;
				if (next == NULL)
				{
					prev->next = cur;
				}
				else
				{
					next = next->next;
					if (next == NULL)
					{
						prev->next = cur;
					}
				}
			}
		}
		ListNode* realhead = pphead->next;
		free(pphead);
		return realhead;
	}
	//测试代码
int main()
{
	ListNode*n6 = (ListNode*)malloc(sizeof(ListNode));
	if (n6)
	{
		n6->val = 53;
		n6->next =NULL;		
	}
	ListNode*n5 = (ListNode*)malloc(sizeof(ListNode));
	if (n5)
	{
		n5->val = 53;
		n5->next = n6;

	}
	ListNode*n4 = (ListNode*)malloc(sizeof(ListNode));
	if (n4)
	{
		n4->val = 666;
		n4->next = n5;
	
	}
	ListNode*n3 = (ListNode*)malloc(sizeof(ListNode));
	if (n3)
	{
		n3->val = 133;
		n3->next = n4;

	}
	ListNode*n2 = (ListNode*)malloc(sizeof(ListNode));
	if (n2)
	{
		n2->val = 133;
		n2->next = n3;

	}
	ListNode*head = (ListNode*)malloc(sizeof(ListNode));
	if (head)
	{
		head->val = 999;
		head->next = n2;
	
	}
	ListNode* list = head;
	while (head)
	{
		printf("%10d->", head->val);
		head = head->next;
	}
	printf("NULL\n");
	head = list;
	while (head)
	{
		printf("%10p->", head);
		head = head->next;
	}
	printf("NULL\n");
	head = list;
	ListNode* sortNode = deleteDuplication(head);
	ListNode* cpylist = sortNode;
	while (sortNode)
	{
		printf("%10d->", sortNode->val);
		sortNode = sortNode->next;
	}
	printf("NULL\n");
	sortNode = cpylist;
	while (sortNode)
	{
		printf("%10p->", sortNode);
		sortNode = sortNode->next;
	}
	printf("NULL\n");
	system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值