题目:
- 给你一个链表,删除链表的倒数第
n
个结点,并且返回链表的头结点。
示例:
- 输入: h e a d = [ 1 , 2 , 3 , 4 , 5 ] , n = 2 head = [1,2,3,4,5], n = 2 head=[1,2,3,4,5],n=2
- 输出: [ 1 , 2 , 3 , 5 ] [1,2,3,5] [1,2,3,5]
解题思路一:
先遍历一遍链表,计算链表长度。然后找到第n - k - 1
的位置,删除第n - k
位置的元素。
C++版
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int k) {
auto dummy = new ListNode(-1);
dummy->next = head;
int n = 0;
for(auto p = dummy; p; p = p->next) n++;
auto p = dummy;
for(int i = 0; i < n - k - 1; i++) p = p->next;
p->next = p->next->next;
return dummy->next;
}
};
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)
解题思路二:双指针法
定义快慢指针fast
和slow
,fast
先走n+1
步,然后fast
和slow
同时走,直到fast
走到NULL
为止,此时slow
走到了要删除的元素的前一个位置,直接slow->next=slow->next->next
删除倒数第n
个节点。
C++
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode* fast = dummy;
ListNode* slow = dummy;
while(n-- && fast != NULL) fast = fast->next;
fast = fast->next;
while(fast != NULL){
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return dummy->next;
}
};
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
1
)
O(1)
O(1)