删除排序链表中的重复元素 II 试试这题
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3
整体思路:这题特别容易错,因为可能会考虑不周全,但是大体思想就是用三个指针,prev,cur,next遍历整个链表,如果cur和next的val相等就让next继续往下走cur不动,知道next的val与cur的值不相等,这时让prev直接指向next即可,再把中的结点free掉就完成啦
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* deleteDuplicates(struct ListNode* head){
if(head == NULL || head->next == NULL)
return head;
Node* prev = NULL;
Node* cur = head;
Node* next = cur->next;
while(next)
{
if(cur->val != next->val)//如果cur和next的val不相等,三个指针同时往后走
{
prev = cur;
cur = next;
next = next->next;
}
else
{
//###如果next==NULL就直接让prev指向NUL
while(next && cur->val == next->val)//如cur和next的val相等,就让next走到两个指针val不相等为止
{
next = next->next;
}
//释放到中间节点
while(cur != next)
{
Node* del = cur;
cur = cur->next;
free(del);
}
if(prev)
prev->next = next;
else
head = next;//如果头部数重复数字
cur = next;
if(next)//###next不为NULL
next = next->next;
}
}
return head;
}
主要有三种情况,有两种很特殊,一种是前部的数字都是重复的,一种是最后的数字都是重复的,只有加上prev!=NULL的条件就可以了,如果头部全是重复数字就直接让prev指向next(此时已经跳出循环)然后head指向next,如果尾部全是重复数字也不影响前面的程序,只要在最后加上next!=NULL的条件,让空指针不要解引用就可以了