【LeetCode】每日一题:移除链表元素 [C语言实现]

简介: 【LeetCode】每日一题:移除链表元素 [C语言实现]

203. 移除链表元素 - 力扣(LeetCode)

题目:

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

示例1:

image.png

输入: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.直接使用原来的链表来进行删除操作。(直接删除)


2.设置一个虚拟头结点再进行删除操作。(创建虚拟头节点)


思想1:直接删除

解释:直接删除就是在原来头节点的位置之上,直接进行删除等于val的节点,我们可以给予两个指针,cur指针用来删除等于val的节点,prev指针用来使删除cur的上一节点指向cur的下一节点,然后free掉cur,但是还有一种例外,如果第一个是等于val,我们想要删除的元素呢?所以我们在遍历整个链表之中,需要对以上两种情况进行考虑。


image.png

image.png

代码实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val){
     struct ListNode* cur = head,* prev = NULL;
     while(cur != NULL)
     {
         //删除
         if(cur->val == val)
         {
             if(prev == NULL)
             { //1.头节点的值等于val
                cur = head->next;
                free(head); //删除头节点
                head = cur;
             }else
             {
                 //2.删除等于val的节点
                 prev->next = cur->next;
                 free(cur);
                 cur = prev->next;
             }
         }else
         {
             //往后继续寻找
             prev = cur;
             cur = cur->next;
         }
     }
     return head;
}

思想2:创建虚拟头节点

解释:我们可以创建一个新(虚拟)的头节点,利用我们学过的单链表尾插的形式,将原头节点head开始不等于val的节点进行尾插(分为空链表和非空链表两种情况),不等于val的节点在往后寻找前进行free掉即可。我们利用cur指针遍历原链表,用tail指针记录每次尾插后的位置,以免下次尾插需要回头再来寻找,降低了时间复杂度。最重要的一点是,在cur往后挪动之后,我们还需要将虚拟头节点的tail->next置为空,否则会出现野指针的情况。


image.png

image.png

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val){
     struct ListNode* cur = head;
     struct ListNode* newhead = NULL,* tail = NULL;
     while(cur != NULL)
     {
          if(cur->val != val)
          {
              //头插(空链表和非空链表)
              if(tail == NULL)
              {
                  newhead = tail = cur;
              }
              else
              {
                  tail->next = cur;
                  tail = tail->next;
              }
              //cur往后走,tail的next一定得置空,因为尾节点必须置空
              //(可以将code1在循环结束code2的位置置空)。
              cur = cur->next;
              tail->next = NULL; //code1
          }
          else
          {
              //删除掉等于val的节点,往后寻找
              struct ListNode* del  = cur;
              cur = cur->next;
              free(del);
          }
     }
     /* // code2
        if(tail)
        tail->next = NULL;
     */
    return newhead;
}


目录
相关文章
|
11天前
|
存储 C语言
C语言程序设计核心详解 第九章 结构体与链表概要详解
本文档详细介绍了C语言中的结构体与链表。首先,讲解了结构体的定义、初始化及使用方法,并演示了如何通过不同方式定义结构体变量。接着,介绍了指向结构体的指针及其应用,包括结构体变量和结构体数组的指针操作。随后,概述了链表的概念与定义,解释了链表的基本操作如动态分配、插入和删除。最后,简述了共用体类型及其变量定义与引用方法。通过本文档,读者可以全面了解结构体与链表的基础知识及实际应用技巧。
|
11天前
|
存储 算法 C语言
C语言手撕实战代码_循环单链表和循环双链表
本文档详细介绍了用C语言实现循环单链表和循环双链表的相关算法。包括循环单链表的建立、逆转、左移、拆分及合并等操作;以及双链表的建立、遍历、排序和循环双链表的重组。通过具体示例和代码片段,展示了每种算法的实现思路与步骤,帮助读者深入理解并掌握这些数据结构的基本操作方法。
|
17天前
|
存储 测试技术 C语言
C语言实现链表的各种功能
本文详细介绍了如何使用C语言实现链表的各种功能,包括链表节点结构的定义与操作函数的实现。链表作为一种常用的数据结构,具有节点自由插入删除、动态变化等特点。文中通过`link_list.h`和`link_list.c`两个文件,实现了链表的初始化、插入、删除、查找、修改等核心功能,并在`main.c`中进行了功能测试。这些代码不仅展示了链表的基本操作,还提供了丰富的注释帮助理解,适合作为学习链表的入门资料。
|
1月前
|
存储 算法
LeetCode第86题分隔链表
文章介绍了LeetCode第86题"分隔链表"的解法,通过创建两个新链表分别存储小于和大于等于给定值x的节点,然后合并这两个链表来解决问题,提供了一种简单易懂且操作原链表的解决方案。
LeetCode第86题分隔链表
|
1月前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
23天前
|
C++ 索引
leetcode 707.设计链表
本文提供了解决LeetCode 707题"设计链表"的C++实现,包括单链表的节点定义和类方法实现,如添加节点、获取节点值、删除节点等。
|
6天前
|
C语言
C语言里的循环链表
C语言里的循环链表
|
1月前
|
算法
LeetCode第92题反转链表 II
文章分享了LeetCode第92题"反转链表 II"的解法,通过使用四个指针来记录和更新反转链表段的头部、尾部以及前一个和后一个节点,提供了一种清晰且易于理解的解决方案。
LeetCode第92题反转链表 II
|
3月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
3月前
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表