【LeetCode & 剑指offer刷题】链表题4:22 删除链表中倒数第k个结点(19. Remove Nth Node From End of List)
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
19. Remove Nth Node From End of List
Given a linked list, remove the n-th node from the end of list and return its head.
Example:
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Follow up:
Could you do this in one pass?
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/*方法:双指针法,前面的指针比后面的领先n+1步,往前走,直到前面的指针到达末尾结点,所要信息,可以从落后的指针获取
如果只是查找倒数第n个结点,可以只用领先n步即可
fast领先n+1步,
fast到nullptr,slow到达倒数n+1位置
删除倒数n位置结点即可
(prehead的使用)
*/
class Solution
{
public:
ListNode* removeNthFromEnd(ListNode* head, int n)
{
//防御性编程
if(head == nullptr || n == 0) return head;
ListNode prehead(0); //创建头结点,方便处理只有一个结点或者移除首结点的特殊情况
prehead.next = head; //指向首结点
ListNode* fast = &prehead, *slow = &prehead;
//fast领先n+1步,循环退出时,fast在位置n+1,slow在位置0(prehead位置为0)
for(int i = 1; i<=n+1; i++)
{
fast = fast->next;
// if(fast == nullptr) return nullptr; //对于查找,需要处理如果n小于链表长度的情况
}
//同时移动fast和slow
while(fast != nullptr)
{
fast = fast->next;
slow = slow->next;
} //结果为fast指向最后一个结点之后为nullptr,slow指向倒数第(n+1)个结点 (找到倒数第n+1个结点,方便删除下一个结点)
ListNode* temp = slow->next; //倒数第n个结点
slow->next = slow->next->next; //跳过倒数第n个结点
delete temp; //删除倒数第n个结点
return prehead.next;
}
};
/*
方法二
class Solution
{
public:
ListNode* removeNthFromEnd(ListNode* head, int n)
{
if(head == NULL || n <= 0)
return head;
if(head->next == NULL)
return NULL;
ListNode *p1 = head, *p2 = head;
while(n > 0)
{
p1 = p1->next;
n --;
}
if(p1 == NULL) // 要删除的为head节点
{
head = head->next;
delete p2;
return head;
}
ListNode *pre = head;
while(p1 != NULL)
{
pre = p2;
p1 = p1->next;
p2 = p2->next;
}
pre->next = p2->next;
delete p2;
return head;
}
};
*/