算法day12 删除链表的倒数第N个节点
题目描述

思路一:算正序位置删除
链表的倒数第N个元素即是正序(len-n+1),(我们这里假设链表的长度为len),所以我们可以将这题的思路由找倒数转表为找正数的位置。接下来的整个操作就与普通的删除链表节点没有什么大差异。
代码如下:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode dummyhead(0); //虚拟头节点
dummyhead.next = head;
ListNode *cur = head;
int len = 0;
while(cur){
len++;
cur = cur -> next;
}
cur = &dummyhead;
int cnt = len - n ;
while(cnt--){
cur = cur -> next;
}
ListNode *s = cur -> next;
cur -> next = cur -> next->next;
delete s;
s = nullptr;
return dummyhead.next;
}
时间复杂度:O(n)
空间复杂度:O(1)
思路二:快慢指针
除了第一种思路外,我们也可以尝试设置快慢指针的方式。我们使快指针与慢指针位置相差n,这样快指针迭代到末尾时,慢指针就会迭代到倒数第n-1个位置,接下来进行删除链表的节点的操作即可。这个思路相较于第一个思路具有时间上的优化,它不必再进行一次完全的链表遍历来获得链表长度。
代码如下:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode dummyhead(0);
dummyhead.next = head;
ListNode *fast = &dummyhead;
while(n--){
fast = fast -> next;
}
ListNode *slow = &dummyhead;
while(fast->next){
fast = fast -> next;
slow = slow -> next;
}
ListNode *s = slow -> next;
slow -> next = slow -> next -> next;
delete s;
s = nullptr;
return dummyhead.next;
}
时间复杂度:O(n)
空间复杂度:O(1)
END
浙公网安备 33010602011771号