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

文章讲述了如何删除链表中值为val的节点,采用双指针方法,一个指针prev在cur之前,遍历链表。当遇到值等于val的节点时,根据节点是否为首结点进行特殊处理,然后删除节点并更新指针。最后返回新链表的头结点。
摘要由CSDN通过智能技术生成

目录

 1、题目

 2、思路

 3、实现

 4、结果与总结

-1、完整代码


1、题目

        我们通过阅读题干,可以得到的信息有:传入的数据有,一个链表的头结点,一个用了来判断的val值。需要返回的是完成删除之后的新链表头结点。

 2、思路

        我们继续秉持先一般后特殊的思考方向。我们平时在删除链表元素的过程当中,一般是先让前一个元素的next指针,指向当前元素的next。即:跳过当前元素,使得前一元素和后一元素直接连接。

        在链接完成之后,释放中间结点(free操作),即可完成链表内一个中间元素的删除。

        但是在考虑过一般情况过后,我们已经知道中间元素是val值的情况怎么处理,但是如果链表首结点是val呢?直接删除首结点会造成一些意想不到的情况,因为首结点没有前一结点!那么我们需要针对头结点进行特殊处理,譬如:1、特殊判断头指针的情况。2、在首结点之前虚拟一个头结点,从而把首结点也当作一个中间元素来处理。

        好了,特殊情况和一般情况我们都考虑到过后,我们就可以上手进行实践,来检验我们的算法思想到底正不正确。

3、实现

        本篇文章里采用的是,针对首结点进行特殊判断的方法。即:如果首结点的val符合题意,则将首结点的next结点,设置为新的head结点,从而可以删除值为val的首结点。

    struct ListNode* prev = NULL;
    struct ListNode* cur = head;

        创建两个链表结构体指针,prev在cur之前。cur就是题目传给我们的head结点,prev暂时置为NULL。

    while(cur)
    {
        if(cur->val == val)
        {
            //删除代码
        }
        else
        {
            prev = cur;
            cur = cur->next;
        }
    }

        创建一个循环,当cur的val和val相等,执行删除结点的操作。如果不相等,则需要判断下一个结点的情况,prev前进到cur指针的位置,cur指针指向下一个位置。

    //删除代码
    if(cur == head)//如果首结点是val,要特殊处理
    {
          head = cur->next;
          free(cur);
          cur = head;
    }
    else
    {
           prev->next = cur->next;
           free(cur);
           cur = prev->next;
    }

        在删除代码在书写的时候,我们要分一般情况和特殊情况来讨论。即:特殊:首结点值为val。一般:首结点以外的值为val。

        1、如果首结点的值为val。head指针指向cur的next元素,即调整首结点到下一个结点。释放之前cur指针指向的head空间,再将cur指针指向新的head。

        2、首结点以外的值为val。将prev指针的next,指向cur指针的next,相当于直接跳过cur指针指向的元素,释放cur指针指向的空间,再将cur指针指向prev指针的next(cur永远都在prev的后面)。

4、结果与总结

        leetcode通过。

        我们再来回顾一下该题的一些算法思想和要点。即建立双指针,永远保持一前一后的状态(cur在前,prev在后)。cur指针用来判断当前元素的值是否符合val,prev指针用来在符合题意的情况下,删除cur指针指向的结点(链表的删除一定要知道前一结点的位置!)。

        在该题当中,特殊情况就在于判断首结点的值,除题解之外我们也可以采用一种通法来解决,即:创建一个虚拟头指针,将链表内结点全部变为普通结点,从而实现统一操作。

-1、完整代码

struct ListNode* removeElements(struct ListNode* head, int val)
{
    struct ListNode* prev = NULL;
    struct ListNode* cur = head;

    while(cur)
    {
        if(cur->val == val)
        {
            //判断首结点的情况
            if(cur == head)
            {
                head = cur->next;
                free(cur);
                cur = head;
            }
            //删除
            else
            {
                prev->next = cur->next;
                free(cur);
                cur = prev->next;
            }
        }
        else
        {
            prev = cur;
            cur = cur->next;
        }
    }
    return head;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值