一、题目
给定一个链表,删除链表的倒数第n个节点并返回链表的头指针
例如,
给出的链表为:1->2->3->4->5, n= 2. 删除了链表的倒数第n个节点之后,链表变为1->2->3->5.
二、题解
S1:考虑链表中只有一个节点,而头节点可能被删除的情况,创建虚拟头节点,让它指向链表的头节点;
S2:定义三个变量p1,p2,prep2,初始化时都指向虚拟头节点;
S3:先让p1走n步,然后p1,p2同时走。preP2始终记录p2的前面一个节点;
S4:当p1==NULL时,p2所指的节点即为要删除的倒数第n个节点。使preP2-.next = p2->next->next;即表示删除了p2这个节点
S5:最后返回链表的头节点(不是虚拟头节点,而是虚拟头节点的下一个节点)
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类
* @param n int整型
* @return ListNode类
*/
ListNode* removeNthFromEnd(ListNode* head, int n) {
// write code here
//如果链表只有一个节点,考虑头节点可能被删除的情况
ListNode* pVHead = new ListNode(-1);//创建虚拟头节点
pVHead->next = head;
//创建临时变量p1与p2,都指向头节点
ListNode* p1 = pVHead;
ListNode* p2 = pVHead;
ListNode* preP2 = pVHead;
//先让p1走n步,然后p1和p2同时走
for(int i=0;i<n;i++){
p1 = p1->next;
}
while(p1 != NULL){
p1 = p1->next;
preP2 = p2;//始终记录p2的前一个节点
p2 = p2->next;
}
//当p1为NULL的时候,p2所指的节点即为倒数第n个节点
//要删除p2所指的节点,需要知道p2所指节点的前一个节点,构建新的链接关系
preP2->next = p2->next;
return pVHead->next;
}
};