双指针能够实现:时间复杂度 O(N),空间复杂度 O(1);且只用一次遍历就能得到答案。
思想就是,先让一个指针 i i i 移动,移动n步后,另一个指针 j j j 跟着移动,直到 i i i 到达终点,则 j j j 所指的节点,即为需要删除的节点的上一个节点。若删除的是头节点,则找不到相关的上一个节点,此时 n > 0 n>0 n>0 特殊处理下。
附上代码:
/**
* Definition for singly-linked list.
* 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 {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* l1 = head->next;
ListNode* l2 = head;
while(l1) {
if(n > 0) {
l1 = l1->next;
n--;
} else {
l1 = l1->next;
l2 = l2->next;
}
}
if(n > 0) head = head->next;
else {
l2->next = l2->next->next;
}
return head;
}
};