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;
}
相关推荐
枕星而眠2 分钟前
Linux 线程:原理、属性、实战与面试避坑
linux·运维·c语言·面试
不会编程的懒洋洋12 分钟前
VisionPro 中 几何相交工具 Geometry-Intersection
图像处理·笔记·c#·视觉检测·机器视觉·visionpro
_李小白16 分钟前
【C++学习笔记】新特性之inline变量
c++·笔记·学习
心中有国也有家18 分钟前
hccl 架构拆解:昇腾集合通信库到底在做什么?
人工智能·经验分享·笔记·分布式·算法·架构
~黄夫人~26 分钟前
零基础速通|Windows&Linux 常用命令行对照表大全
linux·运维·windows·笔记·备忘录·整理表格
桀人37 分钟前
C++——模板初阶(收录在专栏C++入门到精通)
开发语言·c++
一直有一个ac的梦想44 分钟前
cmu15445 2025fall lec 18 transactions with two-phase lock
java·开发语言·数据库
JAVA社区1 小时前
Java进阶全套教程(四)—— SpringMVC框架详解
java·开发语言·spring·面试·职场和发展
Lumbrologist1 小时前
【C++】零基础入门 · 第 2 节:变量、基本数据类型与输入输出
java·开发语言·c++
码完就睡1 小时前
C语言——动态内存
c语言·开发语言