L5.【LeetCode笔记】移除链表元素(未完)

1.题目

https://leetcode.cn/problems/remove-linked-list-elements/description/

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

示例 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
输出:[]

提示:

  • 列表中的节点数目在范围 [0, 104]
  • 1 <= Node.val <= 50
  • 0 <= val <= 50
  • 代码模板
cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) 
{
}

2.自解

算法:双指针一次遍历

不加思索写出以下代码

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

会发现报错(null pointer)

分析: 当头结点的需要删除时,执行if判断的else部分

cpp 复制代码
        else
       {
            prev->next=cur->next;
            free(cur);
            cur=prev->next;
       }

prev->next为NULL->next,这是非法的

因此需要先判断prev是否为NULL,如果为NULL则头删**(注意:头删一定要移动头结点)**

cpp 复制代码
        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;
            }
       }

其他注意事项:特殊情况优先判断:是否为空链表

cpp 复制代码
    if (head==NULL)
    return NULL;

完整代码为:

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) 
{
    if (head==NULL)
    return NULL;
    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;
}

提交结果:

3.其他解法

尾插算法,需要找尾,因此需要尾指针tail

不加思索写出以下代码

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) 
{
    if (head==NULL)
    return NULL;
    struct ListNode* newhead=NULL;
    struct ListNode* tail=NULL;
    struct ListNode* cur=head;
    while(cur)
    {
        if (cur->val!=val)
        {
            if (tail==NULL)
            {
                newhead=tail=cur;
            }
            else
            {
                tail->next=cur;
                tail=tail->next;
            }
            cur=cur->next;
        }
        else
        {
            struct ListNode* next=cur->next;
            free(cur);
            cur=next;
        }
    }
    return newhead;
}

添加对tail的判断,改成下面这样就行

cpp 复制代码
        else
        {
            struct ListNode* next=cur->next;
            free(cur);
            cur=next;
        }
    }
     if (tail)
        tail->next=NULL;
    return newhead;
}

完整代码为

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) 
{
    struct ListNode* newhead=NULL;
    struct ListNode* tail=NULL;
    struct ListNode* cur=head;
    while(cur)
    {
        if (cur->val!=val)
        {
            if (tail==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;
}
相关推荐
Elnaij2 分钟前
从C++开始的编程生活(7)——取地址运算符重载、类型转换、static成员和友元
开发语言·c++
chen_ever12 分钟前
golang之go modules
开发语言·后端·golang
大筒木老辈子15 分钟前
Linux笔记---协议定制与序列化/反序列化
网络·笔记
郝学胜-神的一滴20 分钟前
Effective Modern C++ 条款26:避免在通用引用上重载
开发语言·c++·程序人生
草莓熊Lotso23 分钟前
【C++】递归与迭代:两种编程范式的对比与实践
c语言·开发语言·c++·经验分享·笔记·其他
Aczone281 小时前
硬件(六)arm指令
开发语言·汇编·arm开发·嵌入式硬件·算法
YA3332 小时前
java设计模式二、工厂
java·开发语言·设计模式
逐雨~2 小时前
9.8C++作业
开发语言·c++
我爱挣钱我也要早睡!3 小时前
Java 复习笔记
java·开发语言·笔记
Yang-Never4 小时前
Kotlin协程 -> Job.join() 完整流程图与核心源码分析
android·开发语言·kotlin·android studio