Leetcode: 203. 移除链表元素

题目

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

难度:简单

题目链接:203. 移除链表元素

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

方法一:

题目解析:

遍历链表,删除指定元素(val)

代码展示

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode* pre = NULL,*cur = head;
    while(cur)
    {
        if(cur->val == val)
        {
            struct ListNode* next = cur->next;
            free(cur);
            if(pre == NULL) //删除第一个节点时,free之后,head就变成了也指针
            {
                //为了避免head变成野指针
                head = next;
            }
            else
            {
                pre->next = next;
            }
            cur = next;//继续去找元素
        }
        else
        {
            pre = cur;
            cur = cur->next;
        }
    }
    return head; //返回新的头节点
}

删除元素的主要思想

这样的话就要考虑如何找被删除元素的前一个结点,和被删除元素的下一个结点。

于是这里采用双指针

pre 指针 记录前一个结点,cur 记录指向的当前结点

前提是:删去的不是第一个结点的情况下

第一步

第二步

删除的结点是第一个结点时:

即此时的 pre 是NULL ,cur指向的是head(第一个结点),删去结点(free(cur))。

这里free(cur) 会把第一个结点的内存空间释放返回给操作系统,pre->next = next;会出现问题

加上

cpp 复制代码
            if(pre == NULL) //删除第一个节点时,free之后,head就变成了也指针
            {
                //为了避免head变成野指针
                head = next;
            }
            else
            {
                pre->next = next;
            }
            cur = next;//继续去找元素

if(pre == NULL) --- (只有 一个结点 的情况 而且 是要删除的结点)

这种情况直接让 head 指向 next(代表cur->next,这里也就是NULL)

因为 要删除的元素可能不仅仅是一个,也有可能是多个。所以每次删完一个元素的时候,注意pre指针的指向和cur指针的指向

之后再去重复上述第二步,直到cur遍历完链表。

方法二

主要思想:

先让cur指向第一个结点,遍历结点,把不等于val的值给放到新的链表里。然后返回新的链表头指针即可。

代码

cpp 复制代码
struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode* newhead = NULL,*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* tmp = cur;
            cur = cur->next;
            free(tmp);
        }
    }
    if(tail)
        tail->next = NULL;
    return newhead;
}

图解

相关推荐
bug总结3 分钟前
vue+A*算法+canvas解决自动寻路方案
前端·vue.js·算法
_w_z_j_10 分钟前
盛水最多的容器(滑动窗口 双指针)
算法
胖咕噜的稞达鸭23 分钟前
算法入门:专题前缀和:一二维前缀和 寻找数组的中心下标 除自身以外数组的乘积 和为k的子数组 和可被k整除的子数组 连续数组 矩阵区域和
线性代数·算法·矩阵
天赐学c语言23 分钟前
12.13 - 岛屿数量 && C语言中extern关键字的作用
c++·算法·leetcode
AndrewHZ28 分钟前
【图像处理基石】如何入门图像金字塔算法技术?
图像处理·算法·计算机视觉·cv·拉普拉斯变换·图像金字塔
_w_z_j_32 分钟前
全排列问题(包含重复数字与不可包含重复数字)
数据结构·算法·leetcode
7ioik33 分钟前
jvm垃圾回收算法?
jvm·算法
@小码农37 分钟前
LMCC大模型认证 青少年组 第一轮模拟样题
数据结构·人工智能·算法·蓝桥杯
dragoooon341 小时前
[hot100 NO.13~18]
算法
WangLanguager1 小时前
Prototypical Networks 在图像识别中表现如何?
算法