【LeetCode】移除链表元素(C语言)| 图解算法,超详细哦~


《题目难度:简单》

(1)题目描述

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

示例1:

img

输入: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

输出:[ ]

LeetCode链接:203. 移除链表元素


(2)解题思路

1)思路1:找到等于 val 的节点直接删除

  • 定义一个指针 cur,用来遍历链表,找到等于 val 的节点

  • 定义一个指针 prev,保存 cur 的上一个节点的位置

  • 定义一个指针 next,保存 cur 的下一个节点的位置,用来迭代

  • 首先判断 cur 指向节点的值是否等于 val:

  • 如果等于,则要删除这个节点。我们需要将 prev->next 指向 next 指针,然后 free(cur),再将 cur 往前移动到 next 指针的位置,这样就完成对这个节点的删除啦

image-20210830204816063
  • 如果不等于,只需要将 prev 指针和 cur 指针往前移动一位即可,继续遍历链表寻找等于 val 的节点
  • 最后返回头节点指针 head 即可
  • 需要考虑这一点

如果要删除的节点是头节点,所以在删除的时候需要额外判断一下是不是头结点

image-20210830210523275
  • 代码如下
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* removeElements(struct ListNode* head, int val){
    //解题思路:遍历链表,找到满足Node.val == val的节点
    struct ListNode* cur = head;
    struct ListNode* prev = head;  //保存cur的上一个节点位置
    while(cur != NULL)  //遍历链表
    {
        if(cur->val == val)  //找到等于val的节点
        {
            struct ListNode* next = cur->next;  //保存cur的下一个节点位置
            if(head == cur)  //判断cur是否是头节点
            {
                head = next;
            }
            else
            {
                prev->next = next;  //将cur上一个节点和cur下一个节点相连
            }
            free(cur);  //删除等于val的节点
            cur = next;
        }
        else if(cur->val != val)
        {
            prev = cur;
            cur = prev->next; 
        }
    }
    return head;
}

2)思路2:将不等于 val 的节点尾插到一个新链表中

  • 把链表中所有不等于 val 的节点尾插到一个新链表中,相当于删除了等于val的节点
  • 定义一个指针 cur,用来遍历原链表,找到不等于 val 的节点
  • 定义一个指针 newhead,指向新链表的头节点
  • 定义一个指针 tail,保存新链表尾节点的位置
image-20210830211433874
  • 首先判断 cur 指向节点的值是否不等于 val:

  • 如果不等于,则需要将其尾插到新链表中,首次尾插时,新链表为空,我们让 newhead 指向 cur,然后让 tail 指向 cur,更新新链表的尾节点,cur 往后移动一位,指向待遍历的下一个节点,最后将尾节点的 next 指针置空。

image-20210830213802614
  • 如果等于,则要删除这个节点。定义一个指针 next 保存 cur 的下一个节点的位置,然后 free(cur),再将 cur 移动到 next 的位置,继续遍历原链表。
  • 最后返回新链表的头节点指针 newhead 即可
  • 代码如下
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

struct ListNode* removeElements(struct ListNode* head, int val){
    //解题思路:把链表中所有不等于val的节点尾插到一个新链表中,相当于删除了等于val的节点
    struct ListNode* newhead = NULL;  //新链表初始为空
    struct ListNode* tail = newhead;  //记录新链表尾节点的位置
    struct ListNode* cur = head;
    while(cur != NULL)
    {
        if(cur->val != val)  //把链表中所有不等于val的节点尾插到一个新链表中
        {
            if(newhead == NULL)  //新链表为空时
            {
                newhead = cur;
            }
            else  //新链表不为空时
            {
                tail->next = cur;
            }
            tail = cur;  //更新尾节点
            cur = cur->next;  //cur指向原链表中的下一个节点
            tail->next = NULL;  //将尾节点置空
        }
        else if(cur->val == val)
        {
            struct ListNode* next = cur->next;  //保存cur的下一个节点位置
            free(cur);  //删除等于val的节点
            cur = next;
        }
    }
    return newhead;
}

大家快去动手练习一下吧!

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值