给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
示例 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]
思路1:先统计出链表中结点的总数,然后倒退出,要删除的结点正数是第几,然后删除;
ListNode255* removeNthFromEnd(ListNode255* head, int n) {
ListNode255* dummyHead = new ListNode255(0);
dummyHead->next = head;
ListNode255* cur_size = dummyHead;
ListNode255* cur_N = dummyHead;
//统计链表中结点的数量:
int size = 0;
while (cur_size->next) {
size++;
cur_size = cur_size->next;
}
//链表中一共有5个结点:倒数第2个就是size-n:5-2 = 3 正数的第三个;(倒数从1开始,正数从0开始)
int N = size - n;
if (N>=0) {
//寻找第三个结点:
while (N) {
cur_N = cur_N->next;
N--;
}
ListNode255* temp = cur_N->next;
//删除第3个结点:
cur_N->next = cur_N->next->next;
delete temp;
temp = nullptr;
}
return dummyHead->next;
}
思路2:双指针法:
ListNode255* removeNthFromEnd(ListNode255* head, int n) {
ListNode255* dummyHead = new ListNode255(0);
dummyHead->next = head;
ListNode255* fast = dummyHead;
ListNode255* slow = dummyHead;
n++;
//fast指针先向前移动n+1位
while (n && fast != nullptr) {
fast = fast->next;
n--;
}
//此时fast和slow再同时向前移动,直到fast到达末尾:
while (fast != nullptr) {
fast = fast->next;
slow = slow->next;
}
//slow指向要删除结点的前一位:
ListNode255* temp = slow->next;
//删除slow的下一个结点:
slow->next = slow->next->next;
//释放刚才删除的结点:
delete temp;
temp = nullptr;
return dummyHead->next;
}