今日任务
1.删除链表的倒数第N个结点
2.链表相交
3.环形链表
小引:这三个任务都是涉及到双指针
1.删除链表的倒数第N个结点
LeetCode链接
首先,涉及链表的题目,为了方便我们尽量设置虚拟头结点来解答。
这一题我们有个很直观的思路就是通过一次遍历,把所有的链表的结点数给存储在一个变量中,再通过这个变量与N的数学计算来解答
但是我们也可以通过双指针思路,先设立一个快指针向前走N+1次,为什么是N+1次,因为我们多设立了一个虚拟头结点,要先跨过这个虚拟头结点才行。然后再设立一个慢指针,并且同时使快慢指针一直往前移动,直到快指针指向NULL为止。这样快慢指针之间形成了一段长度为N的窗口,之后快慢指针同步向前相当于保持窗口长度不变。这样当快指针到达了末尾指向NULL,另一端的慢指针距离末尾的长度是N,自然就是指向倒数第N个位置了。
其实自己画个图就可以很好理解了
贴出代码
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* slow = dummyHead;
ListNode* fast = dummyHead;
while(n-- && fast != NULL) {
fast = fast->next;
}
fast = fast->next; // fast再提前走一步,因为需要让slow指向删除节点的上一个节点
while (fast != NULL) {
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
// ListNode *tmp = slow->next; C++释放内存的逻辑
// slow->next = tmp->next;
// delete nth;
return dummyHead->next;
}
};