今天讲解两道链表OJ题目。
给你单链表的头结点
head,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
示例

输入:head = [1,2,3,4,5] 输出:[3,4,5] 解释:链表只有一个中间结点,值为 3
方法1【 双指针】
时间复杂度:O(N)
思想:两个指针,faster的速度是slow两倍,则当faster走到结尾时,slow则走到链表中间。
易错:循环条件 
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * struct ListNode *next;
- * };
- */
- struct ListNode* middleNode(struct ListNode* head)
- {
- struct ListNode*faster=head;
- struct ListNode*slow=head;
- while(faster && faster->next)//条件没想到
- {
- faster=faster->next->next;
- slow=slow->next;
- }
- return slow;
- }
给你一个链表的头节点
head和一个整数val,请你删除链表中所有满足Node.val == val的节点,并返回 新的头节点 。
示例

输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
方法1【三指针--无哨兵位】
时间复杂度:O(N)
思想:三个指正,cur负责对比val,tmp负责存储删除元素的下一个元素地址,prve负责存储删除元素的上一个元素地址
易错:

- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * struct ListNode *next;
- * };
- */
- struct ListNode* removeElements(struct ListNode* head, int val)
- {
- struct ListNode*cur=head;
- struct ListNode*prve=NULL;
- while(cur)
- {
- if(cur->val == val)
- {
- struct ListNode*tmp=cur->next;
- free(cur);
- if(prve)
- {
- prve->next=tmp;
- }
- else
- {
- head=tmp;
- }
- cur=tmp;
- }
-
- else
- {
- prve=cur;
- cur=cur->next;
- }
- }
- return head;
-
- }
方法2【双指针---无哨兵位】

- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * struct ListNode *next;
- * };
- */
- struct ListNode* removeElements(struct ListNode* head, int val)
- {
- struct ListNode*newhead=NULL;
- struct ListNode*tail=NULL;
- struct ListNode*cur=head;
- while(cur)
- {
- if(cur->val != val)
- {
- if(newhead == NULL)
- {
- newhead=tail=cur;
- }
- else
- {
- tail->next=cur;
- tail=tail->next;
- }
- cur=cur->next;
- }
- else
- {
- struct ListNode*tmp=cur->next;
- free(cur);
- cur=tmp;
- }
- if(tail)
- {
- tail->next=NULL;
- }
- }
- return newhead;
- }
-
- //❌改进
那有哨兵位怎么写呢?
当然,这道题还可以联系前面顺序表(移除val)。
代码---------→【唐棣棣 (TSQXG) - Gitee.com】
联系---------→【邮箱:2784139418@qq.com】