• LeetCode每日一练 —— 203. 移除链表元素


    🌟 前言

    Wassup guys!我是Edison 😎

    今天是 LeetCode 上的 leetcode 203. 移除链表元素

    Let’s get it!

    在这里插入图片描述



    1. 题目分析

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

    示例 1:
    在这里插入图片描述

    示例 2:
    在这里插入图片描述

    示例 3:
    在这里插入图片描述

    2. 题目图解

    这道题很简单,还是采用 双指针 法,但是要考虑几种情况

    (1)常规情况
     
    (2)链表中有连续的 val
     
    (3)头节点就是 val

    🍑 常规情况

    定义一个 prev 指针指向 NULL;再定义一个 cur 指针指向头节点
    在这里插入图片描述

    1 步:cur 指向的元素不等于 6,那么 prevcur 依次向后挪动(如图所示👇)
    在这里插入图片描述

    2 步:cur 指向的元素不等于 6,那么 prevcur 依次向后挪动(如图所示👇)
    在这里插入图片描述

    3 步:此时 cur 指向的元素等于 6,那么元素 6 置为 NULL,然后让 prevnext 指向元素 3curnext 也指向元素 3 (如图所示👇)
    在这里插入图片描述

    4 步:cur 指向的元素不等于 6,那么 prevcur 依次向后挪动(如图所示👇)
    在这里插入图片描述

    5 步:cur 指向的元素不等于 6,那么 prevcur 依次向后挪动(如图所示👇)
    在这里插入图片描述

    6 步:此时 cur 指向的元素等于 6,那么元素 6 置为 NULL,然后让 prevnext 指向 curnext(如图所示👇)
    在这里插入图片描述

    7 步:当 cur 指向的元素为 时,循环就终止了(如图所示👇)
    在这里插入图片描述

    ✨动图演示
    在这里插入图片描述

    🍑 连续 val 情况

    还是定义一个 prev 指针指向 NULL;再定义一个 cur 指针指向头节点(如图所示👇)。
    在这里插入图片描述

    1 步:cur 指向的元素不等于 6,那么 prevcur 依次向后挪动(如图所示👇)
    在这里插入图片描述

    2 步:cur 指向的元素不等于 6,那么 prevcur 依次向后挪动(如图所示👇)
    在这里插入图片描述

    3 步:此时 cur 指向的元素等于 6,那么删除该元素,然后让 prevnext 指向 curnextcur 指向下一个元素(如图所示👇)
    在这里插入图片描述

    4 步:此时 cur 指向的元素还是等于 6,那么删除该元素,然后让 prevnext 指向 curnextcur 指向下一个元素(如图所示👇)
    在这里插入图片描述

    5 步:此时 cur 指向的元素还是等于 6,那么删除该元素,然后让 prevnext 指向 curnextcur 指向下一个元素(如图所示👇)
    在这里插入图片描述

    6 步:此时 cur 指向的元素不是 6,那么 prevcur 依次向后挪动(如图所示👇)
    在这里插入图片描述

    7 步:此时 cur 指向的元素等于 6,那么删除该元素然后让 prevnext 指向 curnextcur 指向 ,终止循环(如图所示👇)
    在这里插入图片描述

    可以看到,如果链表中有连续的 val,那么做法也是和常规情况一样的。

    🍑 头节点就为 val

    还是定义一个 prev 指针指向 NULL;再定义一个 cur 指针指向头节点(如图所示👇)。
    在这里插入图片描述

    此时可以发现一个问题,如果是按照常规情况来算的是,cur 指向的元素等于 6,那么删除该元素,然后让 prevnext 指向 curnextcur 指向下一个元素。

    但是此时 prev 指向的元素为 curnext 怎么能够赋值给 呢?显然是不行的,得另想办法!

    其实很简单,我们再定义一个 curHead 指针指向头节点(如图所示👇)。
    在这里插入图片描述

    这里直接用一个动图来演示整个过程👇
    在这里插入图片描述

    3. 代码实现

    📝 接口代码

    struct ListNode* removeElements(struct ListNode* head, int val){
        struct ListNode* prev, *cur;
        prev = NULL;
        cur = head;
        // 循环的结束条件就是cur等于空
        while (cur) {
            // cur不等于val
            if (cur->val != val) {
                prev = cur; //直接把cur的地址赋给prev,相当于把prev移动到cur的位置上
                cur = cur->next; // cur也向后移动一个位置
            }
            else { // 当cur等于val
                struct ListNode* curHead = cur->next; 
                // 为什么 curHead 的内容为 cur->next, 而不是cur呢?
                // 假设头节点就等于val,那么删除val以后, 就相当于头删
                // 头删之后,如果curHead是内容是cur的地址的话,那么久找不到后面的链表了
                // 所以curHead存的应该是cur->next, 也就是第二个节点的地址
                if (prev == NULL) { // 头节点为val为val的情况
                    free(cur); // 释放掉cur
                    head = curHead; // 更新头节点
                    cur = curHead; // 然后把新的头节点的地址赋给cur
                }
                else { // 头节点不为val为val的情况
                    free(cur); // 释放val元素
                    prev->next = curHead; // 因为curHead存的是cur的next,也就是cur的下一个节点的地址,所以直接赋给prev的next
                    cur = curHead; // 然后让cur指向下一个节点的地址
                }
            }
        }
        return head;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    🌟 提交结果
    在这里插入图片描述

  • 相关阅读:
    区别:秒s、毫秒ms、微秒μs、纳秒ns、皮秒ps、飞秒fs每两级之间的换算以及之间的关系
    charles + postern 抓包教程
    当设计模式遇上万象:探秘适配器模式的神奇变身
    服务器常用的异常及性能排查
    第33节——useRef
    C语言程序设计笔记(浙大翁恺版) 第二周:计算
    Webpack原理 如何打包,看懂这篇文章就够了,面试必备技能
    低代码维格云甘特视图入门教程
    基于单片机的人体健康检测系统
    概念:云计算
  • 原文地址:https://blog.csdn.net/m0_63325890/article/details/125973383