【链表OJ 1】移除链表元素val

简介: 【链表OJ 1】移除链表元素val

 大家好,欢迎来到我的博客,此题是关于链表oj的第一题,此后还会陆续更新博客,如有错误,欢迎大家指正。

来源:https://leetcode.cn/problems/remove-linked-list-elements/description/


题目:


3702a4b6f2654dce93031d11d1fda06c.png


方法一:定义prev和cur指针(双指针)


分析:

       使用两个指针prevcur来遍历链表。prev指针指向当前节点的前一个节点,而cur指针指向当前节点。

在 while 循环中,首先检查当前节点的值是否等于val。如果相等,则需要移除该节点。

如果当前节点的值不等于val,则将prev更新为cur, cur 更新为下一个节点,以继续遍历链表。


思路一:prev不为NULL

  • 如果 prev 不为 NULL,表示当前节点不是头节点,则将 prev->next 指向当前节点的下一个节点,然后释放当前节点 cur 的内存,并更新cur为 prev->next ,即下一个要检查的节点。

f4101f16eacf473eb884eaf59a11a62f.gif

思路二: prev 为 NULL

  • 如果 prev 为 NULL,表示当前节点是头节点,则将 cur 更新为头节点的下一个节点,释放头节点 head 的内存,并更新 head 为新的头节点 cur

429cc2c4c26d438c906410dd270dfccb.gif

最后,返回更新后的链表头指针 head

该代码的目的是移除链表中所有值为 val 的节点,同时释放相应的内存。

代码实现:

struct ListNode* removeElements(struct ListNode* head, int val)
{
  struct ListNode* prev = NULL, * cur = head;
  while (cur)
  {
    if (cur->val == val)
    {
      if (prev)
      {
        prev->next = cur->next;
        free(cur);
        cur = prev->next;
      }
      else
      {
        cur = head->next;
        free(head);//会把指针域next给free掉,因为它也是结构体的成员
        head = cur;
      }
    }
    else
    {
      prev = cur;
      cur = cur->next;
    }
  }
  return head;
}


执行:

f0f91c551a22437a94fecaa32be3b243.png


方法二:链表尾插


大致思路:

移除链表中所有值为val的节点,并使用尾插法构建一个新的链表,返回新链表的头指针。原始链表中不满足条件的节点会被保留,而满足条件的节点会被移除并释放内存。


尾插的思路:

函数使用三个指针cur、newhead 和 tail 来遍历和构建新的链表。

在 while 循环中,首先检查当前节点的值是否等于 val 。如果不等于 val ,则执行尾插操作将该节点添加到新链表中。


顺序:

  1. 如果 tail 为 NULL,表示当前节点是新链表的第一个节点。将newhead和 tail 都指向当前节点cur
  2. 接着,将 cur 更新为下一个节点,并将 tail->next 设置为 NULL,确保新链表断开
  3. 此时 tail 不为 NULL,表示当前节点需要添加到新链表的尾部。将 tail->next 指向当前节点 cur ,然后更新 tail 为 tail->next,新链表链接起来实现尾插。
  4. 接着持续2的操作


如果当前节点的值等于 val ,则需要移除该节点。将 cur 更新为下一个节点,并释放当前节点 del 的内存。

最后,返回新链表的头指针 newhead

画图:

image.gif


代码实现:

//尾插
struct ListNode* removeElements(struct ListNode* head,int val)
{
  struct ListNode*cur=head;
  struct ListNode *newhead=NULL,*tail=NULL;
 while(cur)
{
    if(cur->val!=val)
    {
      if(tail==NULL)
        {
      newhead=tail=cur;
    }
      else
    {
          tail->next=cur;
        tail=tail->next;
    }
        cur=cur->next;//  这两条语句不可以调换顺序,否则tail->next=null
      tail->next=NULL;//cur=cur->next,这样写的话会尾插失败
    }
     else
  {
       struct ListNode*del=cur;
       cur=cur->next;
       free(del);//会把指针域next给free掉,因为它也是结构体的成员
  }
 }
    return newhead;
 }


代码执行:

cc5cb6d0fe634f3f8e2dc0d5691e8955.png

    好了博客就分享到这里了,感谢你的来访!

相关文章
|
2月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
37 1
|
4月前
|
程序员
【刷题记录】移除链表元素
【刷题记录】移除链表元素
|
2月前
|
存储 Java
数据结构第三篇【链表的相关知识点一及在线OJ习题】
数据结构第三篇【链表的相关知识点一及在线OJ习题】
29 7
01_移除链表元素
01_移除链表元素
|
2月前
【LeetCode 06】203.移除链表元素
【LeetCode 06】203.移除链表元素
33 0
|
4月前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
5月前
【数据结构OJ题】复制带随机指针的链表
力扣题目——复制带随机指针的链表
55 1
【数据结构OJ题】复制带随机指针的链表
|
5月前
【数据结构OJ题】环形链表II
力扣题目——环形链表II
36 1
【数据结构OJ题】环形链表II
|
4月前
|
存储 C语言
【数据结构】c语言链表的创建插入、删除、查询、元素翻倍
【数据结构】c语言链表的创建插入、删除、查询、元素翻倍
【数据结构】c语言链表的创建插入、删除、查询、元素翻倍
|
4月前
|
Python
【Leetcode刷题Python】203.移除链表元素
文章提供了三种删除链表中特定值节点的方法:迭代法、虚拟节点迭代删除法和递归法,并给出了相应的Python实现代码。
28 0