题目:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
leetcode链接
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
思路:
方法一:建立一个首元结点,指向头结点,扫描一趟链表,并记录链表结点个数len。然后第二次扫描链表,定义指针cur,定义指针prev指向cur的前一个结点,当cur到len-n的位置,则是需要删除的结点,使prev->next=prev->next->next。删除cur指向的结点。
方法二:建立一个首元结点,指向头结点。定义fast指针和slow指针,都指向首元结点。fast指针先走n+1步,接着两个指针同时走,直到fast指针移至末尾,指向null。slow后面的结点就是要删除的结点,删除即可。
代码(方法一):
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution { //删除链表的倒数第N个结点 两趟扫描实现
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* cur = dummyHead->next;
int len = 0;
while (cur != NULL) {
len++;
cur = cur->next;
}
int rest = len - n;
cur = dummyHead->next;
ListNode* prev = dummyHead;
while (rest--) {
prev = cur;
cur = cur->next;
}
prev->next = cur->next;
delete cur;
head = dummyHead->next;
delete dummyHead;
return head;
}
};
代码(方法二):
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution { //删除链表的倒数第N个结点 一趟扫描实现
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* fast = dummyHead;
ListNode* slow = dummyHead;
while (n-- && fast != NULL) {
fast = fast->next;
}
fast = fast->next;
while (fast != NULL) {
fast = fast->next;
slow = slow->next;
}
ListNode* cur = slow->next;
slow->next = slow->next->next;
delete cur;
head = dummyHead->next;
delete dummyHead;
return head;
}
};