【数据结构---10】在线OJ练习题

题目描述:

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针

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

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/

思路分析:

1.三指针法,创建三个指针,第一个作为我们自己创建的头节点,第二个和第三个负责找出重复的区间
2.遍历的终止条件是第三个指针为空,当第二个指针所在节点的值与第三个指针所在节点的值相等,说明重复,第二个指针不动,第三个指针继续往后走,它们的值不相等时,说明已经找到重复的区间
3.删除操作,将头节点的next指向第二个指针的next,将此时的第二个指针free然后置空,重复操作,直到第二个指针与第三个指针重合,说明全部删除关闭
4.新创建一个head,指向我们创建的头节点的next,将我们创建的头节点free置空防止内存泄漏
5.返回head指向的链表
6.注意极端情况:
<1>链表可能为空,或者链表只有一个节点
<2>链表可能全都是重复的
<3>链表可能一开始就是重复的
<4>删除完之后,链表可能还没有遍历完,第三个节点应该继续往后走
<5>申请的内存空间用完及时释放,避免内存泄漏

代码示例:

class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
	     if (pHead == NULL || pHead->next == NULL)
	     {
		      return pHead;
	     }
	     
	     ListNode* first =(ListNode*)malloc(sizeof(ListNode));
	     first->next=pHead;
	     ListNode* newhead=first;
	     ListNode* mid = pHead;
	     ListNode* second=pHead->next;
	     
	     while(second!=NULL)
	     {
	            while (second!=NULL&&mid->val==second->val)
	            {
			        second=second->next;
		    }
		    
	            //中间有空隙,说明中间有重复区间
	            if (mid->next!=second)
	            {
		                while (mid!= second)
		                {
		                    first->next=mid->next;
		                    free(mid);
		                    mid=NULL;
		                    mid=first->next;
		                }
		                if(second!=NULL)
		                {
			            second=second->next;
		                }
	            }
	            else
	            {
	                first=mid;
	                second=second->next;
	                mid=mid->next;
	            }
	      }
	      ListNode* head=newhead->next;
	      free(newhead);
	      newhead=NULL;
	      return head; 
    }
};

猜你喜欢

转载自blog.csdn.net/Austin_Yan/article/details/89811507