先直接给上代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteDuplicates(struct ListNode* head) {
int a[300];
int i=0,k=0,n=0;
if(head==NULL||head->next==NULL)
return head; //判空,解决特殊情况
struct ListNode* point=head;
struct ListNode* pre=point->next;
struct ListNode* hand=head;
while(point->next!=NULL)
{
a[i]=point->val;
if(pre->val==a[i])
{
n++;
struct ListNode* N=pre->next;
pre=N;
point->next=N;
if(k==0&&pre==NULL)
{
head=NULL;
return head;
}
if(pre==NULL)
{
hand->next=NULL;
return head;
}
}
else
{
k++;
point=pre;
pre=point->next;
if(k==1&&n!=0)
{
head=point;
hand=head;
k=0;
n=0;
}
else
{
hand->next=point;
if(point->next!=NULL)
{
if(point->val==pre->val)
{
n=1;
}
else
n=0;
}
if(n==0)
hand=point;
}
n=0;
}
i++;
}
return head;
}
要解决这一个题目,大体思路并不难,将数存入数组然后进行重复判断,如果为空我们则将当前节点的前一个节点指向后一个节点来删除本节点,但是这样做有一个非常关键的点,因为本题要求我们需要删除节点本身,所以判断这个节点“可不可信”也就是是否能加入我们的最终链表很关键。
在笔者写的代码中,用hand这个指针,意在就像手一样,如果代码可信就将其用“手”纳入我们的链表,进行标记。
那么如何判断该节点是否可信呢?
笔者用n这个哨兵来判断是否可信。当节点进行到循环中时如果它在之后未进行删除操作的话,那么说明此节点我们没有检索到重复的,因此判断其可信。
不过只是这样的话还会遇到很多情况,但代码逻辑是完整的,大家如果按照此思路遇到了问题可以用笔者的代码盘一盘逻辑。
遇到问题评论区讨论哦🥰
随缘更新~