思路:双指针
1、首先,判断所给链表节点个数,若最多只有一个节点,则返回空
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
if(head == NULL || head -> next == NULL) {
return (head -> next);//如果最多只有一个节点,则返回空
}
2、定义两个指针
struct ListNode* fast = head;
struct ListNode* slow = head;//定义一个快指针一个慢指针
3、让快指针先走,使快慢指针相隔n个位置
//让快指针先走,走到和慢指针相隔n个位置的地方
int i = 1;
while(i <= n) {
fast = fast -> next;
i++;
}
4、此时即对应类似“[1,2,3,4,5] n=5”这样的情况,则直接返回头节点
//如果快慢指针相隔n个位置的地方为空,则说明此时的倒数第n个节点为头节点
if(fast == NULL) {
return(head -> next);
}
5、让快慢指针一起走,快指针指向最后一个节点的时候,慢指针正好指向所找节点的上一个
//快慢指针一起走,快指针指向最后一个节点的时候,慢指针正好指向所找节点的上一个
while(fast -> next) {
fast = fast -> next;
slow = slow -> next;
}
6、将慢指针的下一个节点指向慢指针的下下个节点,从而完成对所找指针的删除
//将慢指针的下一个节点指向慢指针的下下个节点,从而删除所找指针
slow -> next = slow ->next -> next;
return head;
}
完整代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
if(head == NULL || head -> next == NULL) {
return (head -> next);
}
struct ListNode* fast = head;
struct ListNode* slow = head;
int i = 1;
while(i <= n) {
fast = fast -> next;
i++;
}
if(fast == NULL) {
return(head -> next);
}
while(fast -> next) {
fast = fast -> next;
slow = slow -> next;
}
slow -> next = slow ->next -> next;
return head;
}