【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;
}


目录
相关文章
|
2月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
38 1
|
2月前
【LeetCode 27】347.前k个高频元素
【LeetCode 27】347.前k个高频元素
38 0
|
22天前
|
存储 算法 C语言
【C语言】深入浅出:C语言链表的全面解析
链表是一种重要的基础数据结构,适用于频繁的插入和删除操作。通过本篇详细讲解了单链表、双向链表和循环链表的概念和实现,以及各类常用操作的示例代码。掌握链表的使用对于理解更复杂的数据结构和算法具有重要意义。
203 6
|
26天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
49 5
|
1月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
90 4
|
2月前
|
存储 缓存 C语言
C语言:链表和数组有什么区别
C语言中,链表和数组是两种常用的数据结构。数组是一种线性结构,元素在内存中连续存储,通过下标访问,适合随机访问且大小固定的情况。链表由一系列不连续的节点组成,每个节点存储数据和指向下一个节点的指针,适用于频繁插入和删除操作的场景,链表的大小可以动态变化。
|
1月前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
67 0
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
63 6
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
125 2