双指针算法之快慢指针(二):力扣【寻找链表的第N个点】leetcode-876、19
看完本文,可以去解决力扣的 867 题和 19 题
以往参考:双指针算法之快慢指针(一):力扣【判断链表是否有环】leetcode-141、142
直奔主题,上面的那一篇文章,是对于有环的链表的处理,判断是不是有环,寻找环的开始结点,其实在实际场景中,同样需要查询,查询链表的中间结点,或者查询链表的倒数多少位置的结点等等。
1、寻找链表的中点-leetcode-876(简单)
如果链表的长度是奇数,那么返回链表的中间结点。
如果链表的长度是偶数,那么返回链表的中间结点靠右边的结点。
有了上一次文章的铺垫,下面直接上代码
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode *fast,*slow;
fast = slow = head;
while (fast != NULL && fast->next != NULL) {
fast = fast->next->next; // 一次两步
slow = slow->next; // 一次一步
}
// slow 就在中间位置
return slow;
}
};
有人可能会有疑问,为什么偶数长度的时候没有看见处理?
其实稍微画几个步骤就能够明白了
我们看一下步骤 2
1、如果此时链表长度是 3 ,奇数的时候;
fast->next = NULL,不满足while循环的条件 while (fast != NULL && fast->next != NULL);
所以返回的 slow 就是 2,就是当前链表的中点
2、同样还是步骤2,如果此时链表长度是 4 ,偶数的时候;
fast->next != NULL,满足while循环的条件 while (fast != NULL && fast->next != NULL);
于是就到了步骤3,此时fast 快指针指向的是 5 ,是 NULL,慢指针 slow指向的是 3,就是中点偏右的点
2、删除链表的倒数第N个结点(中等)
这道题相对而言就更简单了。
使用快慢指针,速度都是一步,快指针先走 n 步,随后快慢指针再一起开始前进
等到快指针指向 NULL 的时候,慢指针的位置就是倒数第N个结点了,随后删除即可
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *fast,*slow;
fast = slow = head;
//fast先走n步,如果到头,倒数的n就是第一个
while (n-- >0) {
fast = fast->next;}
if (fast == NULL) {
return head->next;}
while (fast != NULL && fast->next != NULL) {
fast = fast->next;
slow = slow->next;
}
//删除
slow->next = slow->next->next;
return head;
}
};