【LeetCode】移除链表元素、反转链表、链表的中间节点

🧑‍💻作者: @情话0.0
📝专栏:《LeetCode》
🔖题目链接:移除链表元素、反转链表、链表的中间节点


一、移除链表元素(203)

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

示例一

在这里插入图片描述

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例二

输入:head = [], val = 1
输出:[]

示例三

输入:head = [7,7,7,7], val = 7
输出:[]

解题思路:

  对于这道题,定义一个当前指针从第一个结点开始比对,那么就会有两种情况:第一种情况为当前结点不是要移除的结点,则将当前指针向后移动进行下一个结点的比对;第二种情况就是当前结点是要移除的结点,对于这种情况还要分为两种,一种就是该结点为链表的第一个结点,只需将链表头指针和当前指针同时向后移动即可,另一种就是为链表中结点,则需要让被移除结点的前驱结点指向它的后继结点,由于此链表为单链表,当你找到链表中要被删除结点时无法获取到它的前驱结点,所以需要从找到第一个非移除结点时就要标记当前结点的前驱结点,以便于后续移除结点。
在这里插入图片描述

代码:

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

二、反转链表(206)

  给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例一

在这里插入图片描述

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例二

在这里插入图片描述

输入:head = [1,2]
输出:[2,1]

示例三

输入:head = []
输出:[]

解题思路:

  对于这道题,可以选择从头遍历的方式将原链表中的每一个结点取下通过头插的方式形成一个新链表

代码:

struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* cur=head;
    struct ListNode* p=NULL;
    struct ListNode* q=NULL;
    while(cur)
    {
        q=cur->next;
        cur->next=p;
        p=cur;
        cur=q;
    }
    return p;
}

三、链表的中间结点(876)

  给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

示例一

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.

示例二

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。

解题思路:

  对于这道题,就要用到在链表当中经常用到的快慢指针,快指针意思是每次向后移动两步。
  这道题要注意的点为循环的终止条件,若结点个数为奇数个,则终止条件为fast->next==NULL;若结点个数为偶数个,则终止条件为fast==NULL。题目中说的结点个数为偶数时返回第二个结点,若将条件改为返回第一个结点,那么相应的判断条件要改变。

代码:

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode* fast=head;
    struct ListNode* slow=head;
    while(fast&&fast->next)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    return slow;
}

对于这些题目都是自己的见解,若有不足或有更好的方法烦请指点一二,谢谢各位刷题大佬!

在这里插入图片描述

  • 40
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 40
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

情话0.0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值