203. 移除链表元素-c语言

题目来源:力扣

题目描述:给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

本题有两种解决方法

目录

代码1:

 代码2


示例 1:

203. 移除链表元素-c语言_第1张图片

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1
输出:[]

示例 3:

输入:head = [7,7,7,7], val = 7
输出:[]

代码1:
 

struct ListNode* removeElements(struct ListNode* head, int val){
     
    struct ListNode* prev=NULL;
    struct ListNode* cur=head;
    while(cur){
        if(cur->val!=val){
            prev=cur;
            cur=cur->next;
        }else{
            if(prev==NULL){
                head=cur->next;
                free(cur);
                cur=head;
            }else{
                 prev->next=cur->next;
            free(cur);
            cur=prev->next;
            }
        }
    }
    return head;
}

 思路:我们逐段进行分析

我们使用两个指针,一前一后

203. 移除链表元素-c语言_第2张图片

 使cur先指向头,prev在cur之前(最开始为空),然后我们对cur的val进行判断,如果cur的val不等于题给的val,说明不需要删除该节点,我们让prev=cur,然后cur指向next即可,若cur的val与题给val相等,说明需要删除节点,我们让prev的next指向cur的next(prev在cur之前),然后我们释放掉cur,接着让cur指向prev的next即可,如果我们此时提交,就会发现有错误,示例3是过不了的,我们对代码进行解析,发现最开始时cur的val就等于val,此时进入循环,prev的next需要进行指向,但此时的prev为空,所以会出现空指针问题,也就是说,我们有可能需要进行头删,所以我们再次进行判断,即else里我们加的if,如果prev为空,我们进行头删。让head指向cur的next,然后释放cur,cur再指向head即可

203. 移除链表元素-c语言_第3张图片

 代码2

struct ListNode* removeElements(struct ListNode* head, int val){
    //if(head==NULL){
    //    return NULL;
    //}
     struct ListNode* newhead=NULL;
     struct ListNode* cur=head;
     struct ListNode* tail=NULL;
     while(cur){
         if(cur->val!=val){
             if(newhead==NULL){
                 newhead=tail=cur;
             }else{
                 tail->next=cur;
                 tail=tail->next;
             }
             cur=cur->next;
         }else{
             struct ListNode* next=cur->next;
             free(cur);
             cur=next;
         }
     }
     if(tail)
        {
            tail->next=NULL;
        }
     return newhead;
}

思路:

我们创建一个新节点为新的头节点,将符合条件的节点尾插到新节点,最后返回即可

我们创建newhead和cur,还有tail节点,tail是用来指向newhead的尾节点,不然每次我们都要遍历新链表,我们对原链表进行遍历,如果val不等于cur的val,说明要将该节点尾插到newhead,不过在尾插前,我们要先判断是否为第一个节点,即newhead和tail都为NULL,此时我们要单独处理,其余情况我们将tail的next指向cur,然后tail向后移动即可,最后再让cur向后移动,如果不等于,说明要删除该节点,我们先保存cur的next,然后释放cur,cur指向next即可,我们此时提交,会出现错误,如果最后一个节点是我们要删除的,那么最后tail的next是有问题的,所以我们最后单独处理,将tail的next置为空即可,我们再次提交的话,还是会出现问题,空链表无法处理,我们对其单独处理,即前三行我屏蔽的代码,接着再次提交,示例3出现问题,我们分析知道,全部删除的话,最后newhead和tail都为空,所以我们最后对tail进行判断,如果tail不为空,也就是说我们的newhead是有节点的,我们将tail的next置为空,否则我们直接返回newhead,此时newhead为空,也就是空链表和全删除的情况我们都可以处理,所以我们删除前三行单独处理空链表的代码即可(不删也无所谓)

203. 移除链表元素-c语言_第4张图片

 

你可能感兴趣的:(链表,数据结构,c++,c语言,算法)