🧑💻作者: @情话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;
}
对于这些题目都是自己的见解,若有不足或有更好的方法烦请指点一二,谢谢各位刷题大佬!